简体   繁体   English

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

[英]How to write a shell extension in C++?

This seemed like a common question but after doing some searching, I wasn't really able to find my answers. 这似乎是一个常见的问题,但经过一些搜索,我真的无法找到答案。 There is an article on this here: 这里有一篇文章:

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

But it's for a very old version of Visual Studio. 但它适用于Visual Studio的旧版本。 I'm using VS 2008, so the instructions and interfaces don't seem to match what I'm seeing. 我正在使用VS 2008,所以说明和界面似乎与我所看到的不相符。

I want to create a simple shell extension using C++ that creates a context menu for files with extension .GZ. 我想使用C ++创建一个简单的shell扩展,为扩展名为.GZ的文件创建上下文菜单。 When right clicking on these files, I should be able to click my context menu item and have a callback in code to do some sort of operation on that file. 当右键单击这些文件时,我应该能够单击我的上下文菜单项并在代码中进行回调以对该文件执行某种操作。

Other context menu items would do things like spawn modless dialogs to accept user input before executing some action. 其他上下文菜单项将执行诸如生成无模式对话框之类的操作,以在执行某些操作之前接受用户输入。

From what I've seen, ATL is used for this but I have never used ATL, so all of the object types and interfaces are very confusing to me. 从我所看到的,ATL用于此,但我从未使用过ATL,所以所有的对象类型和接口都让我很困惑。 It wouldn't be so bad if I had a proper tutorial or documentation to read. 如果我有适当的教程或文档可供阅读,那就不会那么糟糕了。

Can anyone help me out? 谁能帮我吗? Isn't there some sort of tutorial out there that isn't 10 years old? 是不是有一些不是10年的教程?

I can't tell you exactly how to write a shell extension, but I will provide a number of tips. 我无法确切地告诉你如何编写shell扩展,但我会提供一些提示。 Writing a Shell Extension offers some significant advantages over the much simpler “registry-only” method: 编写Shell扩展比简单的“仅限注册表”方法提供了一些显着优势:

  • With a Shell Extension, you can dynamically create a context menu item (or submenu) that is more relevant to the selected file(s). 使用Shell扩展,您可以动态创建与所选文件更相关的上下文菜单项(或子菜单)。 For example, if you are writing a Shell Extension for zip files, it is possible to create a submenu within the context menu that shows the entire contents of the zip. 例如,如果您正在为zip文件编写Shell扩展,则可以在上下文菜单中创建一个子菜单,该子菜单显示zip的全部内容。
  • You can handle multiple files simultaneously, which may be more beneficial not just for performance purposes but also so that you can work out what to do based on the selection as a whole rather than just for each file. 您可以同时处理多个文件,这不仅有助于提高性能,还可以根据整体选择而不仅仅针对每个文件来确定要做的事情。

Some of the downfalls to Shell Extensions are: Shell Extensions的一些缺陷是:

  • Substantially increased complexity. 大大增加了复杂性。 Be prepared to spend a lot of effort on this to get it working. 准备好花费大量精力来实现它。 Have a home-espresso machine installed next to your computer and/or hire someone to make you coffee. 在您的计算机旁安装家用浓缩咖啡机和/或雇用某人为您做咖啡。

  • Substantially increased difficulty in debugging. 调试的难度大大增加。 Ditto about coffee. 同样关于咖啡。

It's difficult to write a Shell Extension because they can be very hard to debug. 编写Shell扩展很困难,因为它们很难调试。

  • Shell Extensions are loaded by the explorer.exe process, and without specific configuration of Explorer, you need to force-quit the explorer.exe process so that you can install a newer version of your Shell Extension. ShellExtensions由explorer.exe进程加载,如果没有特定的Explorer配置,则需要强制退出explorer.exe进程,以便安装较新版本的Shell扩展。 There is a way to get Explorer to unload DLLs that it is no longer using, but you should only do this on a development machine and not on a deployment target: 有一种方法可以让Explorer卸载它不再使用的DLL,但是您应该只在开发计算机上而不是在部署目标上执行此操作:

    1. In RegEdit, browse to the following key: 在RegEdit中,浏览到以下键:

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

    2. Add a new DWORD key called “AlwaysUnloadDLL” and set its value to 1. 添加一个名为“AlwaysUnloadDLL”的新DWORD键,并将其值设置为1。

    3. Restart explorer. 重启资源管理器。

    This works most of the time, but there may still be times where you need to close Explorer because the Shell Extension was not unloaded. 这在大多数情况下都有效,但有时您可能需要关闭资源管理器,因为未卸载Shell扩展。

  • Keep in mind that your Shell Extension may be loaded by other applications, for example, if you right-click on a file with an applications “open file” dialog, then your Shell Extension will be loaded into that application, and not Explorer. 请记住,其他应用程序可能会加载Shell扩展,例如,如果右键单击带有应用程序“打开文件”对话框的文件,则Shell扩展将加载到该应用程序中,而不是资源管理器。

  • If your Shell Extension causes a runtime error, quite often the result will simply be that your context menu item does not show, very rarely will you be told that your Shell Extension failed to load or that it caused a runtime error. 如果Shell扩展导致运行时错误,通常结果只是您的上下文菜单项未显示,很少会被告知您的Shell扩展无法加载或导致运行时错误。
  • Configuration can be hard, even with an installation, registry data needs to be created in several places, and depending where you want your context menu to show, the places in the registry may differ between different versions of Windows. 配置可能很难,即使安装,需要在多个位置创建注册表数据,并且根据您希望上下文菜单显示的位置,注册表中的位置可能在不同版本的Windows之间有所不同。

What you'll need to do: 你需要做什么:

  • Visual Studio offers some shortcuts to creating Shell Extensions, but basically you'll need to create a COM DLL. Visual Studio提供了一些创建Shell Extensions的快捷方式,但基本上您需要创建一个COM DLL。 A Shell Extension for context menu items must implement both the IContextMenu interface and the IShellExtInit interface. 上下文菜单项的Shell扩展必须同时实现IContextMenu接口和IShellExtInit接口。
  • In the IShellExtInit::Initialize() method, you can obtain the selected files from the IDataObject parameter. IShellExtInit::Initialize()方法中,您可以从IDataObject参数中获取所选文件。 From memory, the data is in “Drag-n-Drop” format, so you need to get an HDROP handle from the IDataObject and query the files from there (this is from memory, it may actually be different than as I described here, so proceed with caution). 从内存中,数据采用“Drag-n-Drop”格式,因此您需要从IDataObject获取HDROP句柄并从那里查询文件(这是来自内存,它实际上可能与我在此描述的不同,所以谨慎行事)。
  • Once your DLL is ready to be “installed”, you must copy it somewhere, and then run regsvr32 to make sure it is registered. 一旦您的DLL准备好“安装”,您必须将其复制到某处,然后运行regsvr32以确保它已注册。
  • Follow this guide to know where to put registry keys. 请按照本指南了解放置注册表项的位置。
  • There may be issues with 64-bit Windows, if you build a 32-bit DLL it may not load in 64-bit Explorer… so keep this in mind if you are having trouble with 64-bit Windows. 64位Windows 可能存在问题,如果您构建32位DLL,则可能无法在64位资源管理器中加载...因此,如果您在使用64位Windows时遇到问题,请记住这一点。
  • Your DLL will actually have two GUIDs associated with it. 您的DLL实际上有两个与之关联的GUID。 I can't remember exactly how it works, but one GUID refers to the DLL itself and the other refers to the actual Shell Extension. 我不记得它是如何工作的,但是一个GUID引用DLL本身而另一个引用实际的Shell扩展。 Make sure you use the GUID of the actual Shell Extension when creating keys in the registry where a GUID is required. 在需要GUID的注册表中创建密钥时,请确保使用实际Shell扩展的GUID。

All things considered… (tl;dr) 考虑到所有事情......(tl; dr)

Weigh up the costs of whether a Shell Extension is worth it. 权衡Shell扩展是否值得的成本。 If you want to create menu items dynamically based on the selected files, then a Shell Extension may be the only way. 如果要根据所选文件动态创建菜单项,则Shell扩展可能是唯一的方法。 If you want to handle all files simultaneously then you'll probably need a Shell Extension as well. 如果你想同时处理所有文件,那么你可能也需要一个Shell扩展。

An alternative to the context menu method, could be to have a drag-n-drop target on the user's desktop or something. 上下文菜单方法的替代方法可以是在用户的桌面上具有拖放目标或其他东西。 Explore other ways that you could have the user submit your files to your application, because a Shell Extension is often far more effort than it is worth. 探索可以让用户将文件提交到应用程序的其他方式,因为Shell扩展通常比它的价值要大得多。 I found this out the hard way and I think everyone else has too. 我发现这很困难,我认为其他人也都有。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为adobe air(或flex)编写c / c ++扩展 - how to write c/c++ extension for adobe air(or flex) 如何在 Z6CE809EACF900BA125B40FABD90FABD90392E 中运行在 Z6CE809EACF900BA125B40FABD92E 中的 Z6CE809EACF900BA125Bshell 中编写一个 cp function (在 linux shell 中) - how to write a cp function (in linux shell ) in c++ that runs in background? C++ - Windows - 如何(写入 && 读取)命令 shell - C++ - Windows - How to (write into && read from) command shell 如何在 Windows 上编写 C++ FireFox 3 插件(非扩展)? - How to write a C++ FireFox 3 plugin (not extension) on Windows? C ++ Shell上下文菜单扩展 - C++ Shell Context Menu Extension 如何在Ruby-C ++扩展中编写C ++类中的非静态方法? - How to write non-static method in C++ class in Ruby-C++ extension? C ++上下文菜单外壳扩展内的级联子菜单 - Cascade submenus inside context menu shell extension with c++ 如何编写一个c ++程序,通过从shell运行来编译自己? - How do I write a c++ program that will compile itself by being run from the shell? 文件写入在PHP扩展C / C ++(Linux)中不起作用 - File write not working in PHP extension c/c++ (linux) 扩展到Web服务器以使用C ++编写脚本? - Extension to web server to write scripts using C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM