`
yzd
  • 浏览: 1818074 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Windows Shell扩展系列文章 1 - .NET 4 编写Windows Shell上下文菜单扩展

 
阅读更多
<p><a href="http://1code.codeplex.com/releases"><strong><span style="text-decoration: underline;"><span style="color: #3d81ee;">示例代码下载</span></span></strong></a>: <a href="http://1code.codeplex.com/releases/view/62253#DownloadId=215068"><strong>C#</strong></a><strong>, </strong><a href="http://1code.codeplex.com/releases/view/62253#DownloadId=215141"><strong>VB.NET</strong></a></p>
<p></p>
<p>在MSDN论坛,大量的开发人员经常问道这样一个问题:</p>
<blockquote>
<p><span style="font-size: small;">如何编写.NET代码开发Windows Shell扩展?</span></p>
</blockquote>
<ul>
<li><a href="http://social.msdn.microsoft.com/Forums/en-US/clr/thread/7ceb44d5-dce8-4197-ac55-f0f4fb59eeb4/"><span style="color: #3d81ee;">http://social.msdn.microsoft.com/Forums/en-US/clr/thread/7ceb44d5-dce8-4197-ac55-f0f4fb59eeb4/</span></a></li>
<li><a href="http://social.msdn.microsoft.com/Forums/en-US/clr/thread/7ce0c480-59e3-4732-a608-1974a908e44a/"><span style="color: #3d81ee;">http://social.msdn.microsoft.com/Forums/en-US/clr/thread/7ce0c480-59e3-4732-a608-1974a908e44a/</span></a></li>
<li><a href="http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/1428326d-7950-42b4-ad94-8e962124043e"><span style="color: #3d81ee;">http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/1428326d-7950-42b4-ad94-8e962124043e</span></a></li>
<li>
<a href="http://social.msdn.microsoft.com/Forums/en-US/clr/thread/63d04f72-5c71-40a9-aea3-519c9e9591a6"><span style="color: #3d81ee;">http://social.msdn.microsoft.com/Forums/en-US/clr/thread/63d04f72-5c71-40a9-aea3-519c9e9591a6</span></a> </li>
</ul>
<p>在.NET Framework 4问世之前,使用.NET编写进程内的Windows Shell 扩展是不被支持的。开发人员不得不使用native C++进行编写。原因是.NET 4之前的CLR只允许一个版本的CLR运行在同一进程内。CLR项目经理Jesse Kapan在<a href="http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/1428326d-7950-42b4-ad94-8e962124043e"><span style="color: #3d81ee;">此论坛帖</span></a>中对这个问题有详细阐述。</p>
<p></p>
<p>随着.NET 4引入了<a href="http://blog.csdn.net/silverlightshanghai/archive/2009/08/25/4482880.aspx"><span style="color: #3d81ee;">CLR in-process side-by-side特性</span></a>,使用.NET 4或未来更高版本.NET编写Windows Shell扩展变成了可能。在.NET 4中CLR支持下列情况的In-Proc SxS:</p>
<p>1. v2.0和v4.0共存</p>
<p>2. v1.1和v4.0共存</p>
<p>而V1.1和V2.0则是不能够被同时加载到进程中。也就是说,进程中&lt;4.0的CLR只能存在一个实例,这样做的原因非常简单:&lt;4.0的CLR版本本身是不支持In-Proc SxS的,也就是说v1.1和v2.0一旦在同一个进程内加载是会出现各种各样的问题的。并且,我们不希望因为要支持SxS而去修改v1.1和v2.0,这样做的代价太大,同时也会把整个问题域变得更加复杂,因此最后决定不支持&lt;4.0的CLR多于一个实例。当然了,&gt;=4.0的CLR是可以多个并存的,也就是说V4.0,V5.0,v6.0,等等,都是可以和平共处在同一个进程内。原因很简单,&gt;4.0的CLR是In-Proc SxS Aware的。</p>
<p></p>
<p>解释了那么多理论的东西,那我究竟该如何编写.NET代码开发Windows Shell 扩展呢?</p>
<p>本系列文章将逐一为你介绍使用.NET开发Windows Shell 上下文菜单扩展,Icon扩展,Drag-and-drop扩展,缩略图扩展,Icon overlay扩展等的详细开发方法和示例。</p>
<p></p>
<p>从最常见的Windows Shell 上下文菜单扩展开始说起。</p>
<p></p>
<p>示例代码 (<a href="http://1code.codeplex.com/releases"><strong><span style="text-decoration: underline;"><span style="color: #3d81ee;">示例代码下载</span></span></strong></a>)</p>
<p><strong>CSShellExtContextMenuHandler</strong>: Shell context menu handler (C#) <br><strong>VBShellExtContextMenuHandler</strong>: Shell context menu handler (VB.NET)<br><strong>CppShellExtContextMenuHandler</strong>: Shell context menu handler (C++)</p>
<p></p>
<h2>示例演示</h2>
<p>当你在Visual Studio 2010中成功编译CSShellExtContextMenuHandler示例,你会得到CSShellExtContextMenuHandler.dll。随后,如你的操作系统是x86的,编译并安装CSShellExtContextMenuHandlerSetup(x86)。如你的操作系统是x64的,编译并安装CSShellExtContextMenuHandlerSetup(x64)。</p>
<p>安装完后,找到任何一个.cs文件。在Windows Explorer中右键该文件。你会看到 “Display File Name (C#)” 上下文菜单项。该菜单项就是由我们的上下文菜单扩展示例添加的。点击该菜单项,你会看到一个消息框显示该.cs文件的完整路径。</p>
<p></p>
<p><a href="http://images.cnblogs.com/cnblogs_com/Jialiang/201103/201103230936529589.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Jialiang/201103/201103230936556816.png" border="0" alt="image" width="400" height="188"></a></p>
<p></p>
<h2>实现细节</h2>
<p>A. 创建和设置工程</p>
<p>在Visual Studio 2010中, 创建一个名为"CSShellExtContextMenuHandler"的Visual C# / Windows / Class Library 工程, 在签名页上,使用强名称密钥文件对该程序集进行签名.</p>
<p><br>-----------------------------------------------------------------------------</p>
<p>B. 执行一个基本组件对象模型 (COM) DLL</p>
<p>所有扩展应用程序都是以COM对象的方式在进程内运行.<br>创建一个基本的.NET COM对象是很简单的事情.您只需要定义一个公共类该类的ComVisible属性设置为true,<br>使用Guid属性设置一个CLSID,显式实现某些COM接口.例如,</p>
<p>[ClassInterface(ClassInterfaceType.None)]<br>[Guid("B1F1405D-94A1-4692-B72F-FC8CAF8B8700"), ComVisible(true)]<br>public class SimpleObject : ISimpleObject<br>{<br> ... // 实现接口<br>}</p>
<p>您甚至不需要自己实现 IUnknown 和类工厂,因为.net 框架已经为您处理好了.</p>
<p>-----------------------------------------------------------------------------</p>
<p>C. 使用上下文菜单应用程序并关联一个文件类型</p>
<p>-----------<br>上下文应用程序的实现:</p>
<p>FileContextMenuExt.cs 文件定义上下文菜单处理程序. 必须继承IShellExtInit and IContextMenu 接口. 在文件ShellExtLib.cs中你可以看到接口可以通过COMImport属性导入</p>
<p>[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]<br>[Guid("000214e8-0000-0000-c000-000000000046")]<br>internal interface IShellExtInit<br>{<br> void Initialize(<br> IntPtr pidlFolder,<br> IntPtr pDataObj,<br> IntPtr /*HKEY*/ hKeyProgID);<br>}</p>
<p>[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]<br>[Guid("000214e4-0000-0000-c000-000000000046")]<br>internal interface IContextMenu<br>{<br> [PreserveSig]<br> int QueryContextMenu(<br> IntPtr /*HMENU*/ hMenu,<br>uint iMenu,<br> uint idCmdFirst,<br> uint idCmdLast,<br>  uint uFlags);</p>
<p> void InvokeCommand(IntPtr pici);</p>
<p>  void GetCommandString(<br> UIntPtr idCmd,<br> uint uFlags,<br> IntPtr pReserved,<br> StringBuilder pszName,<br> uint cchMax);<br>}</p>
<p>[ClassInterface(ClassInterfaceType.None)]<br>[Guid("B1F1405D-94A1-4692-B72F-FC8CAF8B8700"), ComVisible(true)]<br>public class FileContextMenuExt : IShellExtInit, IContextMenu<br>{<br>public void Initialize(IntPtr pidlFolder, IntPtr pDataObj, IntPtr hKeyProgID)<br> {<br> ...<br> }<br><br> public int QueryContextMenu(<br> IntPtr hMenu,<br> uint iMenu,<br> uint idCmdFirst,<br> uint idCmdLast,<br> uint uFlags)<br> {<br>  ...<br> }</p>
<p> public void InvokeCommand(IntPtr pici)<br> {<br> ...<br> }</p>
<p> public void GetCommandString(<br> UIntPtr idCmd,<br> uint uFlags,<br> IntPtr pReserved,<br> StringBuilder pszName,<br> uint cchMax)<br> {<br> ...<br> }<br>}</p>
<p><br>COM操作使得具有最终输出参数的函数看起来是由它返回的该值,PreserveSig属性用于关闭这一特性。 当您不设置(例如,GetCommandString 方法 PreserveSigAttributeIContextMenu)失败时候 ,将引发一个.NET 的异常。<br>例如 Marshal.ThrowExceptionForHR(WinError.E_FAIL) ;在 PreserveSigAttribute 应用于托管的方法的签名时,属性化方法的托管和非托管签名是相同的 (例如QueryContextMenu 方法的 IContextMenu)。保留原始的方法,如果该成员返回多个成功的 HRESULT值签名是必要的,并且您想要检测不同的值。</p>
<p>只有该上下文应用程序被成功注册了,当上下文菜单显示的时候才能被实例化.</p>
<p>1. IShellExtInit接口实现</p>
<p>当上下文扩展COM对象被实例化时,IShellExtInit::Initialize方法将被调用. <br>IShellExtInit::Initialize 提供与在 CF_HDROP 格式中保存一个或多个文件名称的IDataObject 对象的上下文菜单扩展。所选的文件和文件夹通过 IDataObject 对象,您可以枚举。如果 IShellExtInit::Initialize 返回的是S_OK 以外的其他任何值则不能使用上下文菜单扩展.<br><br>在示例代码中, FileContextMenuExt::Initialize 枚举被选中的文件和文件夹. 只有一个文件被选中的时候, 这个方法将保存文件名并返回S_OK供后续处理. 如果没有文件或不止一个文件被选中则函数返回E_FAIL您将不能使用这个上下文应用程序.</p>
<p><br>2. IContextMenu接口实现:</p>
<p>当IShellExtInit::Initialize返回iS_OK后, IContextMenu::QueryContextMenu这个方法将被调用用以获取子菜单项或添加子菜单项. QueryContextMenu方法的实现是非常简单的.上下文扩展使用InsertMenuItem或类是的函数插入子菜单项. 菜单标示符ID必须大于第一个菜单标示符ID且小于最后一个菜单标示符ID. QueryContextMenu必须返回可用的最大的标识符ID并加一的标识符ID. 指定菜单命令标识符的最佳方法是在序列中从0开始.如果上下文菜单扩展无需添加菜单项则QueryContextMenu返回0.<br><br>在示例代码中, 我们插入一个 "Display File Name (C#)"子菜单项并在它的下面加一个分隔符.</p>
<p>IContextMenu::GetCommandString方法被用来检索并返回子菜单项的文本, 例如,为菜单项显示帮助文本. 如果用户选中了上下文菜单中添加的子菜单,应用程序的IContextMenu::GetCommandString 方法将被调用来获取帮助文本并显示在资源管理器的状态栏上ANSI或Unicode的字符集都可以被使用. 示例程序只使用Unicode的uFlags参数, 因为自Windows 2000以后资源管理器只接受Unicode的字符集. 当某个通过上下文菜单扩展安装的子菜单项被选中时,IContextMenu::InvokeCommand的方法在上下文菜单中执行或激发响应此方法所需的操作.</p>
<p>-----------<br>注册为某一类文件的处理程序:</p>
<p>上下文菜单处理程序关联的类文件或文件夹. <br>对于文件类, 程序将被注册在.</p>
<p>HKEY_CLASSES_ROOT/&lt;File Type&gt;/shellex/ContextMenuHandlers</p>
<p></p>
<p>本上下文菜单处理程序的注册是在FileContextMenuExt方法中实现.ComRegisterFunction属性附加到该方法使基本以外的其他用户编写代码的执行注册的 COM 类。注册调用,ShellExtReg.RegisterShellExtContextMenuHandler 方法中,ShellExtLib.cs<br>将该处理程序与特定文件类型相关联。如果文件的类型是以'.'开头的,它会尝试读取 HKCR/ &lt; 文件类型 &gt; 键的可能的默认值包含链接的文件类型的程序 ID。如果默认值不为空,使用作为文件类型的程序 ID 进行注册。</p>
<p>例如, 示例文件关联了 '.cs' 类型的文件. <br>如果您安装了Visual Studio 2010则注册表项HKCR/.cs下就有了一个默认的文件类型'VisualStudio.cs.10.0',所以将使用'VisualStudio.cs.10.0'来取代HKCR/.cs下的文件类型.</p>
<p>HKCR<br>{<br> NoRemove .cs = s 'VisualStudio.cs.10.0'<br> NoRemove VisualStudio.cs.10.0<br> {<br> NoRemove shellex<br> {<br> NoRemove ContextMenuHandlers<br> {<br> {B1F1405D-94A1-4692-B72F-FC8CAF8B8700} = <br> s 'CSShellExtContextMenuHandler.FileContextMenuExt'<br> }<br> }<br> }<br>}</p>
<p>注销的动作将在FileContextMenuExt函数中被实现并执行,类似注册的方法, ComUnregisterFunction属性附加到该方法使基本以外的其他用户编写代码的执行注销的COM 类,执行后将删除注册表项HKCR/CLSID/{&lt;CLSID&gt;} 键 {&lt;CLSID&gt;}和HKCR/&lt;File Type&gt;/shellex/ContextMenuHandlers下的值.</p>
<h2>下载</h2>
<p><a title="http://1code.codeplex.com/releases" href="http://1code.codeplex.com/releases"><span style="color: #3d81ee;">http://1code.codeplex.com/releases</span></a></p>
<p>下载后,在Visual Studio 2010目录下找到CS/VB/CppShellExtContextMenuHandler 示例。</p>
<p></p>
<p>如你有任何反馈或问题,欢迎通过<a href="mailto:onecode@microsoft.com"><span style="color: #3d81ee;">onecode@microsoft.com</span></a>联系我们。</p>
分享到:
评论

相关推荐

    Windows Shell扩展编程完全指南(配套代码).zip

    第七节-如何编写自画上下文菜单项的Shell扩展, 以及如何使上下文菜单扩展响应文件夹窗口背景上的鼠标右击事件 第八节-如何使用信息栏扩展添加定制的信息栏到资源浏览器详细资料列表中 Windows Shell扩展编程完全...

    Windows Shell 扩展编程完全指南

    作者 Michael Dunn, 本资料由同济大学戴维制作 内容:  第一节 - 一步步教你如何编写... 第七节-如何编写自画上下文菜单项的Shell扩展  以及如何使上下文菜单扩展响应文件夹窗口背景上的鼠标右击事件  …………

    Windows+Shell扩展编程完全指南

    第七节-如何编写自画上下文菜单项的Shell扩展, 以及如何使上下文菜单扩展响应文件夹窗口背景上的鼠标右击事件 第八节-如何使用信息栏扩展添加定制的信息栏到资源浏览器详细资料列表中 第九节-如何编写定制文件...

    Windows Shell扩展编程完全指南(含代码)

    第七节-如何编写自画上下文菜单项的Shell扩展, 以及如何使上下文菜单扩展响应文件夹窗口背景上的鼠标右击事件 第八节-如何使用信息栏扩展添加定制的信息栏到资源浏览器详细资料列表中 Windows Shell扩展编程完全...

    Windows Shell扩展编程完全指南

    第七节-如何编写自画上下文菜单项的Shell扩展, 以及如何使上下文菜单扩展响应文件夹窗口背景上的鼠标右击事件 解决了读者提出的两个问题: 自画菜单项和文件夹窗口背景上的上下文菜单. 所附的例子包含两个扩展: ...

    VC Windows Shell扩展 上下文菜单扩展.rar

    VC Windows Shell扩展,设计 制作 上下文菜单扩展,响应右键消息菜单,当用户点击我们添加的菜单项时该方法将被调用。将生成的菜单插入到shell上下文菜单中,返回插入的菜单数,一定要返回正确,包括生成的父菜单也...

    mysql-shell-8.0.18-windows-x86-64bit.zip

    mysql-shell-8.0.18-windows-x86-64bit.zip MySQL Shell is an advanced command-line client and code editor for MySQL. In addition to SQL, MySQL Shell also offers scripting capabilities for JavaScript ...

    Windows Shell扩展编程傻瓜手册大全:上下文菜单扩展

    Windows Shell扩展编程傻瓜手册大全:上下文菜单扩展,详细解说

    Windows Shell扩展编程完全指南(配套代码)

    这是戴维整理的关于 Windows Shell 扩展方面的技术文章,希望方便那些希望学习 Shell 扩展知识而又没有学习资料的人。国内关于 Shell 扩展方面的资料奇缺,希望这个资料能有点用。资料中一部分文章为戴维自己翻译,...

    《Windows Shell扩展编程完全指南》.rar

    《Windows Shell扩展编程完全指南》.rar 《Windows Shell扩展编程完全指南》.rar

    mysql-shell-8.0.20-windows-x86-64bit.zip

    mysql-shell-8.0.20-windows-x86-64bit.zip

    csapp-shell-labcsapp-shell-labcsapp-shell-lab

    csapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp-shell-labcsapp...

    gnome-shell-extension-auto-move-windows-3.28.1-14.el7.noarch.rpm

    官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装

    Windows Shell扩展编程完全指南 chm

    Windows Shell扩展编程完全指南 chm Windows Shell扩展编程完全指南 chm

    Windows Shell扩展编程完全指南(含源码)

    Windows Shell扩展编程完全指南(含源码).chm

    Windows Shell扩展及实例代码

    Shell扩展及其原理的概要说明,常见shell handler及其接口的说明,shell handler的开发过程,附件是一个实例代码。 适合于不怎么了解Shell扩展的人,其实之前我也没弄过Shell扩展,这是搞了 几天Shell扩展的一点心得...

    windows shell扩展编程完全指南

    从网上找到的一些windows shell扩展方面的技术文章及代码,希望方便那些希望学习Shell扩展知识而又没有学习资料的人。本资料由同济大学戴维制作 资料从网上各处收集,版权归原作者所有,由戴维进行了整理与加工,...

    Win Shell扩展编程

    Windows里有着各种各样的扩展,但关于Shell扩展的原理以及如何编写Shell扩展的文档却很少。 如果你想深入地了解Shell各方面的细节,我特别推荐Dino Esposito的著作《Visual C++ Windows Shell Programming》。 但...

    Windows shell扩展程序

    关于什么叫Windows shell扩展程序,这里不作介绍,不懂的同学请google之。这里采用的开发环境为Windows XP+sp3, VS 2005 + sp1 (应该支持VS 2005以上的VS版本,VC 6.0估计不支持)。

Global site tag (gtag.js) - Google Analytics