【问题标题】:Call windows explorer shell extension调用 windows explorer shell 扩展
【发布时间】:2011-08-08 23:11:18
【问题描述】:

有没有办法以编程方式调用作为 shell 扩展的 DLL?我们使用在 Windows 资源管理器上注册 shell 扩展的软件,我需要调用其上下文菜单中可用的项目之一。我没有想要调用的软件源代码。

编辑

此上下文菜单仅在我在 Windows 资源管理器中选择 PDF 文件时出现。所以我需要调用它传递一个 dll 文件。

编辑

注册信息:

[HKEY_CLASSES_ROOT\CLSID{2DC8E5F2-C89C-4730-82C9-19120DEE5B0A}] @="PDFTransformer3.PDFTContextMenu.1"

[HKEY_CLASSES_ROOT\CLSID{2DC8E5F2-C89C-4730-82C9-19120DEE5B0A}\InprocServer32] @="C:\Program Files\ABBYY PDF Transformer 3.0\PDFTContextMenu.dll" "ThreadingModel"="公寓"

[HKEY_CLASSES_ROOT\CLSID{2DC8E5F2-C89C-4730-82C9-19120DEE5B0A}\ProgID] @="PDFTransformer3.PDFTContextMenu.1"

[HKEY_CLASSES_ROOT\CLSID{2DC8E5F2-C89C-4730-82C9-19120DEE5B0A}\可编程]

[HKEY_CLASSES_ROOT\CLSID{2DC8E5F2-C89C-4730-82C9-19120DEE5B0A}\VersionIndependentProgID] @="PDFTransformer3.PDFTContextMenu"

编辑

是否可以使用我想要的动词(不是默认动词)调用ShellExecuteEx?如果是这样,我如何调用我想要的动词(使用 DLL)?

这就是我想调用 PDF 文件的动词:

【问题讨论】:

  • shell 扩展有什么作用?它是什么类型的扩展程序?
  • 它在 pdf 文件中工作。我猜它是一个 COM DLL,但我不确定。
  • 你需要知道它是什么类型的shell扩展才能知道如何调用它。如果您不知道它是什么类型,那么您如何知道要请求哪些 COM 接口?
  • 在弄清楚它是哪种外壳扩展之前,您不会得到答案。有很多不同类型的 shell 扩展。
  • 顺便说一下,+1 是为了补偿那些在不发表任何评论的情况下投了反对票的人。

标签: c# windows delphi shell-extensions


【解决方案1】:

它是一个 COM 对象。你只需要创建它,并传递给它接口(背后有足够的实现)它就可以工作了。

Explorer(即您)将要求外壳扩展程序将项目添加到不同的 HMENU。然后资源管理器(即您)调用菜单项以响应用户。

幸运的是,shell 中的所有东西都是一个接口——所以你可以假装成你想要的任何东西。你只需要read the SDK contract from the other side

记住A shell extension doesn't have to be hosted in Explorer。许多不是。 CommCtrl 的“另存为”对话框中托管了很多内容。


在你的情况下it's even simpler

  • 创建 COM 对象
  • 查询其IShellExtInit接口,调用.Initialize
  • 查询其IContextMenu接口
  • 调用IContextMenu.QueryContextMenu,允许它添加项目到HMENU
  • 致电IContextMenu.Invoke

又是一个从对方读取合同的案例。


一些伪代码:

var
   ClassID: TGUID;
   unk: IUnknown;
   shellext: IShellExtInit;
   dataObject: IDataObject;
   hkeyProgID: HKEY;
   contextMenu: IContextMenu;
   commandInfo: CMINVOKECOMMANDINFO;
begin
   ClassID := ProgIDToClassID('PDFTransformer3.PDFTContextMenu'); 
   unk := CreateComObject(ClassID);

   shellExt := unk as IShellExtInit;

    {
       For shortcut menu extensions, 
          pdtobj identifies the selected file objects,
          hkeyProgID identifies the file type of the object with focus, and 
          pidlFolder is either NULL (for file objects) or specifies the folder 
             for which the shortcut menu is being requested 
             (for folder background shortcut menus).
   }
   shellExt.Initialize(
         nil, //pidlFolder, null for file objects
         dataObject, //IDataObject of the selected file
         hkeyProgID); //HKEY of the file type of the object with focus    

   contextMenu := unk as IContextMenu;
   contextMenu.QueryContextMenu(
         menuHandle, //HMENU, A handle to the shortcut menu. The handler should specify this handle when adding menu items.
         0, //integer, The zero-based position at which to insert the first new menu item.
         100, //The minimum value that the handler can specify for a menu item identifier.
         200, //The maximum value that the handler can specify for a menu item identifier.
         CMF_NORMAL); //optional flags

   contextMenu.InvokeCommand(commandInfo);

这是我从阅读文档和猜测该怎么做中得到的。现在我要尿尿,回家玩传送门2

【讨论】:

  • 我想我不知道这样做。也许有人可以告诉我如何使用 ShellExecuteEx 来调用动词。但是感谢您的帮助。
【解决方案2】:

Rafael,你可以使用IContextMenu 接口。从这里你可以枚举接口返回的条目,然后使用InvokeCommand执行你想要的选项

【讨论】:

  • 听起来不错,但我是 C# 新手。你能给我一个示例或 Delphi 代码吗?
  • 检查这个问题 stackoverflow.com/questions/3777121/… 和 Craig Peterson 的答案。
  • @Rafael,首先我不会在此链接中发布任何代码,只是建议,发布的代码来自 Craig Peterson。此代码可以指导您解决问题,如果没有按预期工作,您可以在 S.O 中发布一个新问题,其中包含帮助您的代码,为您显示部分 which not work
  • @RRUZ,对不起。我的意思是您发布的链接上的来源。
【解决方案3】:

DLL 显然是context-menu extension。如果您想以与 shell 相同的方式调用它,那么您需要托管 DLL 实现的 IContextMenu 接口。几年前,Raymond Chen 就这个主题写了一篇内容丰富的系列文章:

如何托管 IContextMenu

  1. Initial foray
  2. Displaying the context menu
  3. Invocation location
  4. Key context
  5. Handling menu messages
  6. Displaying menu help
  7. Invoking the default verb
  8. Optimizing for the default command
  9. Adding custom commands
  10. Composite extensions - groundwork
  11. Composite extensions - composition

前两篇文章是最重要的。他们首先介绍了如何获取文件的 IContextMenu 接口,然后介绍如何调用该菜单提供的一个或多个命令。本质上,get the IContextMenu interface,填充一个 CMINVOKECOMMANDINFOEX 结构,然后将其传递给接口的InvokeCommand 方法。文章调用TrackPopupMenu 向用户显示菜单,然后使用选择来填充结构,但如果您已经确切知道要运行哪个命令,那么您可以放弃显示菜单。 (不过,您可能仍然需要创建菜单,因为 IContextMenu 对象可能希望首先调用 QueryContextMenu。)

【讨论】:

  • 他为什么不能直接调用ShellExecuteEx?
  • 不知道,@David。他问如何调用 DLL — 但我想您从经验中知道,回答问题 as ask 会给我们带来麻烦。但即使他确实使用了 ShellExecuteEx,他仍然必须通过此过程一次来找出哪些动词可用,因为它们不在注册表中。
  • 如果有人告诉我如何使用 ShellExecuteEx 调用上下文菜单,那就没问题了。我正在研究您发布的链接,但我还没有任何工作。
猜你喜欢
  • 1970-01-01
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-01-12
相关资源
最近更新 更多