调用 Windows 资源管理器 shell 扩展

发布于 2024-11-02 22:06:45 字数 1081 浏览 2 评论 0原文

有没有办法以编程方式调用作为 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 文件的动词:

在此处输入图像描述

Is there any way of calling a DLL that is a shell extension programmatically? We use a software that registers a shell extension on windows explorer, and I need to call one of the items available on its context menu. I do not have the software source code that I want to call.

EDIT

This context menu only appears when I select a PDF file on windows explorer. So i need to call it passing a dll file.

EDIT

Registry information:

[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"="Apartment"

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

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

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

EDIT

Is it possible to call ShellExecuteEx with the verb i want (not the default one)? If so, how do I call the verb I want (which uses the DLL)?

Thats the verb i wanna call for a PDF file:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

-柠檬树下少年和吉他 2024-11-09 22:06:45

该 DLL 显然是一个上下文菜单扩展。如果您想以与 shell 相同的方式调用它,那么您需要托管 DLL 实现的 IContextMenu 接口。几年前,Raymond Chen 撰写了有关此主题的广泛系列:

如何托管​​ IContextMenu

  1. 初步尝试
  2. 显示上下文菜单
  3. 调用位置
  4. 关键上下文
  5. 处理菜单消息
  6. 显示菜单帮助
  7. 调用默认动词
  8. 优化默认命令
  9. 添加自定义命令
  10. 复合扩展 - 基础
  11. 复合扩展- 作文

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

The DLL is evidently a context-menu extension. If you want to call it the same way the shell does, then you want to host the IContextMenu interface that the DLL implements. Several years ago, Raymond Chen wrote an extensive series on this topic:

How to host an 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

The first two articles are the most important. They introduce how to get the IContextMenu interface of a file in the first place, and then how to invoke one or more of the commands offered by that menu. Essentially, get the IContextMenu interface, fill a CMINVOKECOMMANDINFOEX structure, and then pass it to the interface's InvokeCommand method. The articles call TrackPopupMenu to display a menu to the user, and then use the selection to fill the structure, but if you already know exactly which command you want to run, then you can forgo displaying the menu. (You might still have to create the menu, though, since the IContextMenu object probably expects to have QueryContextMenu called on it first.)

┾廆蒐ゝ 2024-11-09 22:06:45

拉斐尔,您可以使用 IContextMenu 界面。从这里您可以枚举接口返回的条目,然后使用 InvokeCommand

Rafael, you can use the IContextMenu Interface. from here you can enumerate the entries returned by the interface and then execute the option which you want using the InvokeCommand

蓦然回首 2024-11-09 22:06:45

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

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

幸运的是,shell 中的所有内容都是一个接口 - 所以您可以假装成任何您想要的东西。您只需要从另一方读取SDK合同< /a>.

记住shell 扩展不会必须托管在资源管理器中。很多都不是。很多内容都托管在 CommCtrl 的“另存为”对话框中。


就您而言更简单

  • 创建 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

It's a COM object. You just need to create it, and pass it interfaces (with enough implementation behind it) it make it work.

Explorer (i.e. you) will ask the shell extension to add items to an different HMENUs. Then Explorer (i.e. you) invokes a menu item in response to the user.

Fortunately everything in the shell is an interface - so you can pretend to be whatever you want. You just need to read the SDK contract from the other side.

Remember: A shell extension doesn't have to be hosted in Explorer. Many aren't. A lot are hosted in the "Save As" dialog from CommCtrl.


In your case it's even simpler.

  • Create the COM Object
  • query for its IShellExtInit interface, and call .Initialize.
  • query for its IContextMenu interface
  • call IContextMenu.QueryContextMenu, allowing it to add items to an HMENU
  • call IContextMenu.Invoke

Again, a case of reading the contract from the other side.


Some pseudo-code:

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);

That's as far as i get from reading documentation and guessing what to do. Now i have to pee, and go home to play Portal 2

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文