Вызов расширения окна проводника Windows - PullRequest
3 голосов
/ 19 апреля 2011

Есть ли способ вызвать DLL, которая является расширением оболочки программно? Мы используем программное обеспечение, которое регистрирует расширение оболочки в проводнике Windows, и мне нужно вызвать один из пунктов, доступных в его контекстном меню. У меня нет исходного кода программного обеспечения, которое я хочу вызвать.

EDIT

Это контекстное меню появляется только тогда, когда я выбираю файл PDF в проводнике Windows. Поэтому мне нужно вызвать его, передав файл DLL.

EDIT

Информация о реестре:

[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} \ Программируемый]

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

EDIT

Можно ли позвонить ShellExecuteEx с нужным мне глаголом (не по умолчанию)? Если да, то как мне вызвать глагол, который я хочу (который использует DLL)?

Вот глагол, который я хочу призвать для файла PDF:

enter image description here

Ответы [ 3 ]

11 голосов
/ 20 апреля 2011

DLL, очевидно, является расширением контекстного меню .Если вы хотите вызвать его так же, как это делает оболочка, то вы хотите host интерфейс IContextMenu, который реализует DLL.Несколько лет назад Рэймонд Чен написал обширную серию на эту тему:

Как разместить IContextMenu

  1. Начальный набег
  2. Отображение контекстного меню
  3. Место вызова
  4. Контекст ключа
  5. Обработка сообщений меню
  6. Отображение справки меню
  7. Вызов глагола по умолчанию
  8. Оптимизация для команды по умолчанию
  9. Добавление пользовательских команд
  10. Композитные расширения - основы
  11. Композитные расширения - композиция

Первые две статьи являются наиболее важными.Они рассказывают, как получить интерфейс IContextMenu файла в первую очередь, а затем, как вызвать одну или несколько команд, предлагаемых этим меню.По сути, получить интерфейс IContextMenu , заполнить структуру CMINVOKECOMMANDINFOEX, а затем передать ее в метод интерфейса InvokeCommand.Статьи вызывают TrackPopupMenu, чтобы отобразить меню для пользователя, а затем использовать выделение, чтобы заполнить структуру, но если вы уже точно знаете, какую команду вы хотите выполнить, то вы можете отказаться от отображения меню,(Возможно, вам все равно придется создать меню, поскольку объект IContextMenu, вероятно, ожидает, что сначала будет вызван QueryContextMenu.)

6 голосов
/ 20 апреля 2011

Рафаэль, вы можете использовать интерфейс IContextMenu. отсюда вы можете перечислить записи, возвращаемые интерфейсом, а затем выполнить желаемую опцию, используя InvokeCommand

2 голосов
/ 20 апреля 2011

Это COM-объект.Вам просто нужно создать его и передать его интерфейсам (с достаточной реализацией), чтобы он заработал.

Исследователь (т.е. вы) попросит расширение оболочки добавить элементы в другие HMENU.Затем Explorer (то есть вы) вызывает пункт меню в ответ пользователю.

К счастью, все в оболочке является интерфейсом - так что вы можете притворяться, что хотите.Вам просто нужно прочитать контракт SDK с другой стороны .

Помните : Расширение оболочки не имеет дляразмещаться в Проводнике .Многие нет.Многие размещаются в диалоговом окне «Сохранить как» в 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);

Это все, что я получаю, читая документацию и догадываясь, что делать.Теперь мне нужно пописать и пойти домой, чтобы поиграть в Portal 2

...