2012-01-10 1 views
17

Это казалось обычным вопросом, но после некоторых поисков я не смог найти ответы. Существует статья об этом здесь:Как написать расширение оболочки в C++?

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

Но это для очень старой версии Visual Studio. Я использую VS 2008, поэтому инструкции и интерфейсы, похоже, не соответствуют тому, что я вижу.

Я хочу создать простое расширение оболочки, используя C++, который создает контекстное меню для файлов с расширением .GZ. При щелчке правой кнопкой мыши по этим файлам я должен щелкнуть элемент контекстного меню и вызвать обратный вызов в коде для выполнения какой-либо операции над этим файлом.

Другие пункты контекстного меню будут делать такие вещи, как нерешительные диалоги, чтобы принять пользовательский ввод перед выполнением какого-либо действия.

Из того, что я видел, для этого используется ATL, но я никогда не использовал ATL, поэтому все типы объектов и интерфейсы меня очень сбивают с толку. Это было бы не так плохо, если бы у меня был подходящий учебник или документация для чтения.

Может ли кто-нибудь помочь мне? Разве нет какого-то учебника, которому не исполнилось 10 лет?

+1

Это на самом деле особенно трудная вещь. Я разработал пункт контекстного меню, когда пользователь щелкнул правой кнопкой мыши по принтерам. Несмотря на то, что в моем коде было всего 40 или около того, было около 1000 строк сгенерированного кода. Хотел бы я быть более полезным, но я не могу поделиться каким-либо кодом, который у меня есть. В качестве подсказки расширение вашей оболочки должно находиться в DLL, и оно должно иметь свой собственный GUID, а DLL необходимо зарегистрировать в regsvr32. Вы хотите реализовать ** BOTH ** интерфейсы IContextMenu и IShellExtInit COM. Есть способ заставить ВС генерировать большую часть этого для вас, но я не помню, как это сделать. – dreamlax

+0

[IContextMenu] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb776095 (v = vs.85) .aspx) doc, а также [IShellExtInit] (http: // msdn. microsoft.com/en-us/library/windows/desktop/bb775096(v=vs.85).aspx) doc. – dreamlax

+0

@dreamlax Я использовал мастер проекта для проекта ATL, но когда я создаю новый класс, он также создает для него интерфейс - мне не нужен интерфейс, но не просто удалить эту функциональность. Плюс я не уверен, почему нужно создать код. –

ответ

24

Я не могу точно сказать, как написать расширение оболочки, но я предоставлю несколько советов. Написание Extension Shell предлагает ряд существенных преимуществ по сравнению с более простым “ реестрового только ” метода:

  • с расширением оболочки, вы можете динамически создать пункт контекстного меню (или подменит), которое является более непосредственным отношением к выбранному файлу (ы). Например, если вы пишете расширение оболочки для zip-файлов, можно создать подменю в контекстном меню, отображающее все содержимое почтового индекса.
  • Вы можете обрабатывать несколько файлов одновременно, что может быть более полезным не только для целей производительности, но и для того, чтобы вы могли решить, что делать на основе выбора в целом, а не только для каждого файла.

Некоторые из крушений к Shell Extensions являются:

  • Существенно увеличилась сложность. Будьте готовы потратить на это много усилий, чтобы заставить его работать. У вас есть домашняя эспрессо-машина рядом с вашим компьютером и/или нанять кого-то, чтобы вы могли выпить кофе.

  • Существенно повышенная сложность в отладке. Тоже о кофе.

Трудно написать расширение оболочки, потому что их можно очень трудно отлаживать.

  • Shell Extensions загружается в explorer.exe процессе, и без определенной конфигурации проводника, необходимо принудительно выйти из explorer.exe процесса, так что вы можете установить новую версию расширения оболочки.Существует способ, чтобы получить проводник для выгрузки библиотек DLL, что она больше не используется, но вы должны делать это только на машине разработчика, а не на цели развертывания:

    1. В RegEdit, перейдите к следующему разделу:

      HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Explorer,

    2. Добавить новый ключ DWORD с именем “ ” AlwaysUnloadDLL и установите его значение равным 1.

    3. перезапускает проводник ,

    Это работает большую часть времени, но все же могут быть моменты, когда вам нужно закрыть Explorer, потому что расширение оболочки не было выгружено.

  • Имейте в виду, что ваше расширение оболочки может быть загружен другими приложениями, например, если вы щелкните правой кнопкой мыши на файле с приложениями “ диалог открытия файла ”, то ваш Extension Shell будут загружены в этом приложении, а не Explorer.

  • Если ваша оболочка Shell вызывает ошибку времени выполнения, довольно часто результат просто будет заключаться в том, что ваш пункт контекстного меню не отображается, очень редко вам сообщают, что расширение оболочки не удалось загрузить или что оно вызвало ошибку времени выполнения.
  • Конфигурация может быть сложной, даже при установке данные реестра должны быть созданы в нескольких местах и ​​в зависимости от того, где вы хотите, чтобы ваше контекстное меню отображалось, места в реестре могут отличаться в разных версиях Windows.

Что вам нужно сделать:

  • Visual Studio предлагает некоторые ярлыки для создания расширений оболочки, но в основном вам нужно создать COM DLL. Расширение оболочки для элементов контекстного меню должно реализовать интерфейс IContextMenu и интерфейс IShellExtInit.
  • В методе IShellExtInit::Initialize() вы можете получить выбранные файлы из параметра IDataObject. Из памяти данные находятся в формате “ Drag-n-Drop ”, поэтому вам нужно получить дескриптор HDROP из IDataObject и запросить файлы оттуда (это из памяти, это может быть иная, чем, как я описал здесь, поэтому будьте осторожны).
  • Как только ваша DLL готова к установке “ ”, вы должны скопировать ее где-нибудь, а затем запустить regsvr32, чтобы убедиться, что она зарегистрирована.
  • Следуйте за нами this guide, чтобы узнать, где ввести ключи реестра.
  • Там может быть проблемами с 64-разрядной Windows, если вы создаете 32-битную DLL, она не может загружаться в 64-разрядный Explorer & hellip; поэтому имейте это в виду, если у вас возникли проблемы с 64-битной Windows.
  • В вашей DLL на самом деле будет два GUIDs, связанные с ним. Я точно не помню, как это работает, но один GUID относится к самой DLL, а другой относится к фактическому расширению оболочки. Убедитесь, что вы используете GUID существующего расширения оболочки при создании ключей в реестре, где требуется идентификатор GUID.

Все вещи считаются & hellip; (tl; dr)

Оцените, стоит ли расширение оболочки. Если вы хотите динамически создавать элементы меню на основе выбранных файлов, расширение оболочки может быть единственным способом. Если вы хотите обрабатывать все файлы одновременно, вам также понадобится расширение оболочки.

Альтернативой методу контекстного меню может быть наличие цели drag-n-drop на рабочем столе пользователя или что-то в этом роде. Изучите другие способы, с помощью которых пользователь может отправлять ваши файлы в приложение, потому что расширение оболочки часто намного больше, чем того стоит. Я нашел это трудным путем, и я думаю, что все остальные тоже.

+3

+1 Awesome Post, с .NET 4 вам стало легче, теперь вы можете писать расширения оболочки в управляемом коде. Упоминаем это здесь, чтобы люди не полностью отговаривались. – blak3r

+0

@ blak3r Это [кажется] (https://stackoverflow.com/a/2194638/321973), чтобы не поощрять. –