17

这似乎是一个常见问题,但经过一番搜索后,我并没有真正找到答案。这里有一篇文章:

http://www.codeproject.com/KB/shell/shellextguide1.aspx

但它适用于非常旧版本的 Visual Studio。我使用的是 VS 2008,所以说明和界面似乎与我所看到的不符。

我想使用 C++ 创建一个简单的 shell 扩展,为扩展名为 .GZ 的文件创建上下文菜单。右键单击这些文件时,我应该能够单击我的上下文菜单项并在代码中进行回调以对该文件执行某种操作。

其他上下文菜单项会执行一些操作,例如生成无模式对话框以在执行某些操作之前接受用户输入。

据我所见,ATL 用于此目的,但我从未使用过 ATL,因此所有对象类型和接口对我来说都非常混乱。如果我有适当的教程或文档可供阅读,那也不会那么糟糕。

谁能帮我吗?那里不是有某种教程不是 10 岁吗?

4

1 回答 1

24

我不能确切地告诉你如何编写一个 shell 扩展,但我会提供一些提示。与简单得多的“仅注册”方法相比,编写 Shell 扩展具有一些显着优势:

  • 使用 Shell 扩展,您可以动态创建与所选文件更相关的上下文菜单项(或子菜单)。例如,如果您正在为 zip 文件编写 Shell 扩展,则可以在上下文菜单中创建一个子菜单,以显示 zip 的全部内容。
  • 您可以同时处理多个文件,这不仅对性能目的更有利,而且您可以根据整个选择而不是仅针对每个文件来确定要执行的操作。

Shell 扩展的一些缺点是:

  • 大大增加了复杂性。准备好为此付出很多努力以使其正常工作。在您的计算机旁边安装一台家用浓缩咖啡机和/或雇人为您煮咖啡。

  • 大大增加了调试的难度。关于咖啡也是如此。

编写 Shell 扩展很困难,因为它们很难调试。

  • Shell Extensions 由explorer.exe进程加载,如果没有 Explorer 的特定配置,您需要强制退出explorer.exe进程,以便您可以安装更新版本的 Shell Extension。有一种方法可以让 Explorer 卸载它不再使用的 DLL,但您应该只在开发机器上而不是在部署目标上执行此操作:

    1. 在 RegEdit 中,浏览到以下键:

      HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer

    2. 添加一个名为“AlwaysUnloadDLL”的新 DWORD 键并将其值设置为 1。

    3. 重启资源管理器。

    这在大多数情况下都有效,但有时您可能仍需要关闭资源管理器,因为外壳扩展未卸载。

  • 请记住,您的 Shell 扩展可能会被其他应用程序加载,例如,如果您右键单击带有应用程序“打开文件”对话框的文件,那么您的 Shell 扩展将被加载到该应用程序中,而不是资源管理器中。

  • 如果您的 Shell 扩展导致运行时错误,结果通常只是您的上下文菜单项未显示,很少会告诉您您的 Shell 扩展加载失败或导致运行时错误。

  • 配置可能很困难,即使是安装,也需要在多个位置创建注册表数据,并且根据您希望上下文菜单显示的位置,注册表中的位置可能在不同版本的 Windows 之间有所不同。

你需要做什么:

  • Visual Studio 提供了一些创建 Shell 扩展的快捷方式,但基本上您需要创建一个 COM DLL。上下文菜单项的外壳扩展必须同时实现IContextMenu接口和IShellExtInit接口。
  • 在该IShellExtInit::Initialize()方法中,您可以从IDataObject参数中获取选择的文件。从内存中,数据采用“Drag-n-Drop”格式,因此您需要从中获取HDROP句柄IDataObject并从那里查询文件(这是来自内存,实际上可能与我在这里描述的不同,所以继续慎用)。
  • 一旦您的 DLL 准备好“安装”,您必须将它复制到某个地方,然后运行regsvr32以确保它已注册。
  • 请按照本指南了解将注册表项放在何处。
  • 64 位 Windows可能存在问题,如果您构建 32 位 DLL,它可能无法在 64 位资源管理器中加载……因此,如果您在 64 位 Windows 上遇到问题,请记住这一点。
  • 您的 DLL 实际上将有两个与之关联的 GUID。我不记得它是如何工作的,但一个 GUID 指的是 DLL 本身,另一个指的是实际的 Shell 扩展。在需要 GUID 的注册表中创建键时,请确保使用实际 Shell 扩展的 GUID。

考虑到所有事情……(tl; dr)

权衡外壳扩展是否值得的成本。如果您想根据所选文件动态创建菜单项,那么外壳扩展可能是唯一的方法。如果您想同时处理所有文件,那么您可能还需要一个 Shell 扩展。

上下文菜单方法的替代方法可能是在用户桌面上放置一个拖放目标或其他东西。探索可以让用户将文件提交到应用程序的其他方法,因为 Shell 扩展通常付出的努力远远超过它的价值。我发现这一点很困难,我认为其他人也有。

于 2012-01-11T20:34:39.093 回答