C++ 如何在C++;?

C++ 如何在C++;?,c++,atl,windows-shell,shell-extensions,C++,Atl,Windows Shell,Shell Extensions,这似乎是一个常见的问题,但在做了一些搜索之后,我真的无法找到我的答案。这里有一篇关于这方面的文章: 但这是一个非常旧版本的VisualStudio。我使用的是VS2008,所以指令和接口似乎与我看到的不匹配 < >我想用C++创建一个简单的shell扩展,它为扩展的文件创建上下文菜单。当右键单击这些文件时,我应该能够单击上下文菜单项,并在代码中进行回调,以便对该文件执行某种操作 其他上下文菜单项将执行一些操作,如生成无模式对话框,以在执行某些操作之前接受用户输入 据我所见,ATL用于此目的,但

这似乎是一个常见的问题,但在做了一些搜索之后,我真的无法找到我的答案。这里有一篇关于这方面的文章:

但这是一个非常旧版本的VisualStudio。我使用的是VS2008,所以指令和接口似乎与我看到的不匹配

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

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

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


有人能帮我吗?有没有不到10年的教程?

我不能确切地告诉您如何编写shell扩展,但我将提供一些提示。与更简单的“仅注册表”方法相比,编写Shell扩展提供了一些显著的优势:

  • 通过Shell扩展,您可以动态创建与所选文件更相关的上下文菜单项(或子菜单)。例如,如果要为zip文件编写Shell扩展名,可以在上下文菜单中创建一个子菜单,显示zip文件的全部内容
  • 您可以同时处理多个文件,这不仅有利于提高性能,而且还可以使您根据整个选择而不仅仅是每个文件来确定要做什么
Shell扩展的一些缺点是:

  • 大大增加了复杂性。准备好在这方面花费大量精力,以使其发挥作用。在你的电脑旁边安装一台家用浓缩咖啡机,或者雇个人给你煮咖啡

  • 大大增加了调试的难度。咖啡也是这样

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

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

  • 在RegEdit中,浏览到以下键:

    HKEY\U本地\U计算机\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer

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

  • 重新启动资源管理器

  • 这在大多数情况下都有效,但可能仍有一些时候需要关闭资源管理器,因为没有卸载Shell扩展

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

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

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

您需要做的是:

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

所有考虑过的事情…(tl;dr) 权衡一下外壳扩展是否值得的成本。如果要基于所选文件动态创建菜单项,则Shell扩展可能是唯一的方法。如果您想同时处理所有文件,那么可能还需要一个Shell扩展名


上下文菜单方法的另一种替代方法是在用户桌面上放置一个拖放目标。探索让用户将文件提交到应用程序的其他方法,因为Shell扩展通常比它值得付出的努力多得多。我很难发现这一点,我想其他人也一样。

这实际上是一件特别困难的事情。我有个孩子