如何用C ++编写shell扩展?

时间:2012-01-10 22:42:24

标签: c++ atl windows-shell shell-extensions

这似乎是一个常见的问题,但经过一些搜索,我真的无法找到答案。这里有一篇文章:

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

但它适用于Visual Studio的旧版本。我正在使用VS 2008,因此说明和界面似乎与我所看到的不相符。

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

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

从我所看到的,ATL用于此但我从未使用过ATL,因此所有的对象类型和接口都让我很困惑。如果我有适当的教程或文档可供阅读,那就不会那么糟糕了。

任何人都可以帮助我吗?是不是有一些不是10年的教程?

1 个答案:

答案 0 :(得分:24)

我无法确切地告诉你如何编写shell扩展,但我会提供一些提示。编写Shell扩展比简单的“仅限注册表”方法提供了一些显着优势:

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

Shell Extensions的一些缺陷是:

  • 复杂性大幅增加。准备好花费大量精力来实现它。在您的计算机旁安装家用浓缩咖啡机和/或雇用某人为您做咖啡。

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

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

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

    1. 在RegEdit中,浏览以下密钥:

      HKEY_LOCAL_MACHINE \ SOFTWARE \微软\的Windows \ CurrentVersion \ Explorer中

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

    3. 重新启动资源管理器。
    4. 这在大多数情况下都有效,但有时您可能需要关闭资源管理器,因为未卸载Shell扩展。

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

    6. 如果您的Shell扩展程序导致运行时错误,通常结果只是您的上下文菜单项未显示,很少会被告知您的Shell扩展程序无法加载或导致运行时错误。< / LI>
    7. 配置可能很难,即使安装,需要在多个位置创建注册表数据,并且根据您希望上下文菜单显示的位置,注册表中的位置可能因Windows的不同版本而不同。

您需要做什么:

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

考虑所有事情......(tl; dr)

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

上下文菜单方法的替代方法可能是在用户的桌面上有一个拖放目标。探索可以让用户将文件提交到应用程序的其他方式,因为Shell扩展通常比它的价值要大得多。我发现这很困难,我认为其他人也都有。