如何开始编写Windows Shell扩展?

3
我正在考虑编写一个Shell扩展,这样当单击文件时,就可以对其执行操作。(就像任何其他上下文菜单一样 :))
我需要插入新的菜单项到上下文菜单中,并针对一个或多个文件执行操作的最小要求是什么?一个比较的例子是,我选择了10个文件并发送到Zip。
我读到需要编写一些非托管代码,但是我的C++非托管代码知识几乎为零,因此我希望尽可能少地进行操作以获得Windows上下文菜单(文件>右键单击)中的菜单项。之后,我想调用一个C#控制台应用程序来进行主处理,那么是否可以从非托管代码调用C#控制台应用程序?
另外,我需要创建哪种类型的Visual Studio项目来创建Windows Shell程序?我应该从以下哪种项目类型中选择:
- Win32控制台应用程序 - MFC应用程序 - Win32项目 - ATL项目 - MFC DLL - CLR控制台应用程序 - 类库 - Makefile项目 - MFC ActiveX控件 - Windows窗体控件库
谢谢!
4个回答

5

这篇MSDN文章将帮助你入门。

你的方法是生成一个进程(由托管代码编写)来执行shell扩展的实际工作,这应该没问题。我建议通过CreateProcess将所选文件作为命令行参数传递。

至于项目类型,你需要生成一个Win32动态链接库(DLL)。在2005年版本中,实际上有一个Win32 Dll项目类型。对于2008年版本(我推断你正在使用),你应该创建一个Win32项目,然后在结果向导中选择DLL作为应用程序类型。


谢谢!这些链接没有提供有关使用VS的建议。您能告诉我应该使用哪种VS项目类型来创建非托管的C++程序吗?请参见我的编辑后的问题。 - Anton P

3
如果你没有Windows和COM的C++经验,一个shell扩展可能不是最容易的项目。
你确定你真的需要编写一个shell扩展吗?
你可以通过注册表轻松地添加一个新的菜单选项(请参见此处的示例),并将该选项的“命令”设置为你的C#可执行文件。
你可以通过在路径中使用%1命令来将所选文件传递给进程。
所有文件的示例注册表条目如下:
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\\*\shell\SomeCmd]
@="Do Some Cmd"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\\*\shell\SomeCmd\command]
@="\"Path to your app\\YourApp.exe\" \"%1\""

注意结尾的%1 - 它将是文件的名称。限制在于,您实际上会为每个文件实例化一次 - 这也将发生在扩展中。注册表条目设置后,它将保留直到您将其删除。

这个过程有点受限制吗?我需要传递参数到C#控制台应用程序,比如所有选定文件的列表。在这种情况下,这种技术会怎样工作?我需要每次重新编写注册表吗? - Anton P
更新了帖子,附上了注册表示例。 - S.Skov
谢谢。这对于非常简单的命令可以起作用。此外,我还需要菜单项具有子项。我不认为这是通过注册表设置实现的... - Anton P

3
虽然完全使用托管代码编写Shell扩展并非不可能(我已经做过),但出于各种原因,这并不被推荐。最大的原因是Shell扩展是进程内扩展,这意味着资源管理器必须将整个CLR加载到其自己的地址空间中,如果您有两个扩展程序编写为不同版本的CLR,则会遇到困难。
除此之外,对于一个如此小的功能来说,这样做是很多额外开销。因此,最好使用C++编写它,因为有许多可用的工具,包括Active Template Library (ATL)。

0

这里有一个使用.NET与非托管客户端的示例:http://groups.google.com/group/codefactory/web/wcf-service-and-unmanaged-c-client

是的,您需要编写非托管代码(C++)来与Shell交互。一些Shell扩展是用C#编写的,但即使是微软也不建议这样做,因为它会在Explorer的进程空间中加载运行时。 您可以在codeproject上找到许多关于编写ContextMenu扩展的文章。它涉及编写实现IContextMenu接口的COM dll,并在注册表中适当地注册。


你能告诉我应该使用哪种 VS 项目类型来创建非托管的 C++ 程序吗?请查看我编辑过的问题。 - Anton P
使用ATL COM DLL - 它预装了注册和取消注册条目。 - A9S6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接