再谈利用SharpShell实现Windows Shell扩展

原创 2016年06月02日 12:38:19

之前写过一篇文章介绍过如何用SharpShell提供的接口去实现Windows PreviewHandler的扩展功能,但用的方法是先实现SharpShell中的各类接口编译DLL,再手动给注册表安装和注册相关内容,但发现这种方法有点折腾,而且不便于部署,后来发现SharpShell本来就自带注册表管理器,使用起来非常方便,而且可以避免自己写注册表出现疏忽。

效果图

Windows PreviewHandler其实是一个COM组件,要实现某种特定文件格式在资源管理器中的预览,需要以下几步
1.注册你的自定义文件后缀
[HKEY_CLASSES_ROOT.example]
@=”examplefile”
2.注册你的PreviewHandler组件
[HKEY_CLASSES_ROOT\CLSID{de6d955a-ba3a-4ce6-962f-85bcfb8bf37f}]
@=”HidasPreview”
“AppID”=”{de6d955a-ba3a-4ce6-962f-85bcfb8bf380}”
“DisplayName”=”HidasPreview”
“Icon”=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,\
00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,66,00,\
6f,00,6e,00,74,00,65,00,78,00,74,00,2e,00,64,00,6c,00,6c,00,2c,00,31,00,30,\
00,00,00

[HKEY_CLASSES_ROOT\CLSID\{de6d955a-ba3a-4ce6-962f-85bcfb8bf37f}\InprocServer32]
@="mscoree.dll"
"Assembly"="HidasRegistry, Version=1.0.0.0, Culture=neutral, PublicKeyToken=87a8ebc60c5813a4"
"Class"="HidasPreview.HidasPreview"
"RuntimeVersion"="v4.0.30319"
"ThreadingModel"="Both"
"CodeBase"="file:///E:/VS Projects/PreviewHandlerSample/HidasRegistry/bin/Release/HidasRegistry.exe"

[HKEY_CLASSES_ROOT\CLSID\{de6d955a-ba3a-4ce6-962f-85bcfb8bf37f}\InprocServer32\1.0.0.0]
"Assembly"="HidasRegistry, Version=1.0.0.0, Culture=neutral, PublicKeyToken=87a8ebc60c5813a4"
"Class"="HidasPreview.HidasPreview"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///E:/VS Projects/PreviewHandlerSample/HidasRegistry/bin/Release/HidasRegistry.exe"

3.为你的自定义文件注册对应的PreviewHandler
[HKEY_CLASSES_ROOT\higetfile\shellex{8895b1c6-b41f-4c1c-a562-0d564250836f}]
@=”{de6d955a-ba3a-4ce6-962f-85bcfb8bf37f}”

可以看到,第二步中注册的程序其实是mscoree.dll,也就是.net虚拟机的初始库,而它的参数则是我们编译的SharpShell程序相关内容,包括程序地址、调用的类以及.NET版本等等。

回来再看程序代码部分,我在代码中继承实现了一个SharpPreviewHandler类

using SharpShell.Attributes;
using SharpShell.SharpPreviewHandler;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace HidasPreview
{
    /// <summary>
    /// The IconPreviewHandler is a preview handler that shows the icons contained
    /// in an ico file.
    /// </summary>
    [ComVisible(true)]
    [COMServerAssociation(AssociationType.ClassOfExtension, ".example")]
    [Guid("DE6D955A-BA3A-4CE6-962F-85BCFB8BF37F")]
    [PreviewHandler]
    public class HidasPreview : SharpPreviewHandler
    {
        /// <summary>
        /// DoPreview must create the preview handler user interface and initialize it with data
        /// provided by the shell.
        /// </summary>
        /// <returns>
        /// The preview handler user interface.
        /// </returns>
        protected override PreviewHandlerControl DoPreview()
        {
            //  Create the handler control.
            var handler = new HidasPreviewHandlerControl();

            //  Do we have a file path? If so, we can do a preview.
            if (!string.IsNullOrEmpty(SelectedFilePath))
                handler.DoPreview(SelectedFilePath);

            //  Return the handler control.
            return handler;
        }
    }
}

可以看到,DoPreview程序主要作用是给资源管理器返回一个PreviewHandlerControl(继承于UserControl)

然后我们可以在程序入口中加入PreviewHandler的注册和删除方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HidasPreview;
using HidasIconHandler;

namespace HidasRegistry
{
    class Program
    {
        static void Main(string[] args)
        {

            HidasPreview.HidasPreview preview = new HidasPreview.HidasPreview();
            HidasIconHandler.HidasIconHandler icon = new HidasIconHandler.HidasIconHandler();
            if (args.Length == 1 && args[0] == "-a")
            {
                SharpShell.ServerRegistration.ServerRegistrationManager.InstallServer(preview, SharpShell.ServerRegistration.RegistrationType.OS32Bit, true);
                SharpShell.ServerRegistration.ServerRegistrationManager.InstallServer(preview, SharpShell.ServerRegistration.RegistrationType.OS64Bit, true);
                SharpShell.ServerRegistration.ServerRegistrationManager.RegisterServer(preview, SharpShell.ServerRegistration.RegistrationType.OS32Bit);
                SharpShell.ServerRegistration.ServerRegistrationManager.RegisterServer(preview, SharpShell.ServerRegistration.RegistrationType.OS64Bit);

                SharpShell.ServerRegistration.ServerRegistrationManager.InstallServer(icon, SharpShell.ServerRegistration.RegistrationType.OS32Bit, true);
                SharpShell.ServerRegistration.ServerRegistrationManager.InstallServer(icon, SharpShell.ServerRegistration.RegistrationType.OS64Bit, true);
                SharpShell.ServerRegistration.ServerRegistrationManager.RegisterServer(icon, SharpShell.ServerRegistration.RegistrationType.OS32Bit);
                SharpShell.ServerRegistration.ServerRegistrationManager.RegisterServer(icon, SharpShell.ServerRegistration.RegistrationType.OS64Bit);
            }

            if (args.Length == 1 && args[0] == "-d")
            {
                SharpShell.ServerRegistration.ServerRegistrationManager.UnregisterServer(preview, SharpShell.ServerRegistration.RegistrationType.OS32Bit);
                SharpShell.ServerRegistration.ServerRegistrationManager.UninstallServer(preview, SharpShell.ServerRegistration.RegistrationType.OS32Bit);
                SharpShell.ServerRegistration.ServerRegistrationManager.UnregisterServer(preview, SharpShell.ServerRegistration.RegistrationType.OS64Bit);
                SharpShell.ServerRegistration.ServerRegistrationManager.UninstallServer(preview, SharpShell.ServerRegistration.RegistrationType.OS64Bit);

                SharpShell.ServerRegistration.ServerRegistrationManager.UnregisterServer(icon, SharpShell.ServerRegistration.RegistrationType.OS32Bit);
                SharpShell.ServerRegistration.ServerRegistrationManager.UninstallServer(icon, SharpShell.ServerRegistration.RegistrationType.OS32Bit);
                SharpShell.ServerRegistration.ServerRegistrationManager.UnregisterServer(icon, SharpShell.ServerRegistration.RegistrationType.OS64Bit);
                SharpShell.ServerRegistration.ServerRegistrationManager.UninstallServer(icon, SharpShell.ServerRegistration.RegistrationType.OS64Bit);
                Console.WriteLine("deleted");
            }

                Console.WriteLine(args.Length);
            foreach(var v in args)
                Console.WriteLine(v);
        }
    }
}

ServerRegistration**

可以帮我们完成上述的步骤2和3,至于步骤1,我们还是需要写一个注册表项让自定义文件和后缀名关联起来。

**

欢迎各位朋友提出宝贵意见

QQ:2961688520

相关文章推荐

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

[ShellExtension]上下文扩展-IContextMenu实现

还是先亮源码下载地址:https://git.oschina.net/xiangmu110/template_IContextMenuExt以下所讲与提供下载的源码不同,但都是一个模子出来的。下面这段...

C# 创建右键菜单和编程

1.在控件上右键,弹出菜单 1.在工具箱里拖一个ContextMenuStrip控件到Form上,设置属性,示例如下图 2.将你要设置右键菜单的控件的Conte...

C#TreeView窗体版点击右键弹出菜单+右键获取信息

整了半天,原来就是加个控件就好使! 添加这个控件contextMenuStrip1,然后TreeView中有个属性contextMenuStrip,在该属性中选中contextMenuStr...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

WinForm中右键菜单的添加

http://hi.baidu.com/pfdong/blog/item/df87a7229371d6e0d6cae20d.html 方法一:给需要添加右键菜单的控件设置ContextMenuS...
  • wyqlxy
  • wyqlxy
  • 2012年04月11日 10:29
  • 1943

Windows下的shell扩展的种类以及相关的实例

表一Windows 外壳扩展类型适用于版本有关的接口描述上下文菜单 Context Menu 文件类和外壳对象Windows 95+IContextMenu, IContextMenu2, or IC...

用C#创建SHELL扩展

 安徽省民航局 周毅(longsoft@ah163.com)一、前言     .NET平台是微软公司推出的作为未来软件运行和开发的环境,C#是微软力荐的在.NET平台下开发应用软件的首选语言。本文将讨...

javascript实现代码高亮原理

转自:https://segmentfault.com/q/1010000003508615 网上有很多的代码高亮库,之前想自己写一个,但是想不出原理。我一开始的想法是把代码赋值给一个变量,...

iOS-NSNotificationCenter通知中心是同步操作还是异步操作

前言最近有个小伙伴到喜马拉雅去面试,面试官问他一个问题就是“通知中心是同步操作还是异步操作?”,小伙伴回答成异步了,然后就是回家等消息,然后就是没有然后了。。。我先举几个小的列子给大家瞅瞅:发送通知-...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:再谈利用SharpShell实现Windows Shell扩展
举报原因:
原因补充:

(最多只允许输入30个字)