Создание обработчиков расширений оболочки
Возможности оболочки можно расширить с помощью записей реестра и .ini файлов. Хотя этот подход к расширению оболочки прост и подходит для многих целей, он ограничен. Например, если вы используете реестр для указания пользовательского значка для типа файла, для каждого файла этого типа будет отображаться один и тот же значок. Расширение оболочки с помощью реестра не позволяет изменять значок для разных файлов одного типа. Другие аспекты оболочки, такие как страница свойств Свойства , которая может отображаться при щелчке правой кнопкой мыши по файлу, не могут быть изменены с помощью реестра.
Более эффективный и гибкий подход к расширению оболочки заключается в реализации обработчиков расширений оболочки. Эти обработчики можно реализовать для различных действий, которые может выполнять оболочка. Перед выполнением действия оболочка запрашивает обработчик расширения, предоставляя ему возможность изменить действие. Распространенным примером является обработчик расширения контекстного меню. Если он реализован для типа файла, он будет запрашиваться каждый раз, когда один из файлов щелкается правой кнопкой мыши. Затем обработчик может указать дополнительные пункты меню для каждого файла, а не иметь одинаковый набор для всего типа файла.
В этом документе описывается, как реализовать обработчики расширений, которые позволяют изменять различные действия оболочки. Следующие обработчики связаны с определенным типом файлов и позволяют указать по файлам:
Обработчик | Описание |
---|---|
Обработчик контекстного меню | Вызывается перед отображением контекстного меню файла. Она позволяет добавлять элементы в контекстное меню по файлам. |
Обработчик данных | Вызывается при выполнении операции перетаскивания с объектами dragShell. Это позволяет предоставить дополнительные форматы буфера обмена для целевого объекта удаления. |
Обработчик удаления | Вызывается при перетаскивании объекта данных в файл или при его перетаскивании в файл. Это позволяет преобразовать файл в целевой объект удаления. |
Обработчик значков | Вызывается перед отображением значка файла. Это позволяет заменить значок файла по умолчанию на пользовательский значок для каждого файла. |
Обработчик страницы свойств | Вызывается перед отображением страницы свойств свойства объекта. Он позволяет добавлять или заменять страницы. |
Обработчик эскизов изображений | Предоставляет изображение для представления элемента. |
Обработчик подсказок | Предоставляет всплывющий текст, когда пользователь навевает указатель мыши на объект. |
Обработчик метаданных | Предоставляет доступ на чтение и запись к метаданным (свойствам), хранящимся в файле. Его можно использовать для расширения представления сведений, подсказок, страницы свойств и функций группирования. |
Другие обработчики не связаны с определенным типом файлов, но вызываются перед некоторыми операциями оболочки:
Обработчик | Описание |
---|---|
Обработчик столбцов | Вызывается Windows Обозреватель перед отображением представления сведений о папке. Она позволяет добавлять настраиваемые столбцы в представление Сведений. |
Обработчик перехватчика копирования | Вызывается при перемещении, копировании, удалении или переименовании объекта папки или принтера. Это позволяет утвердить операцию или наказать вето. |
Обработчик действия перетаскивания | Вызывается при перетаскивании файла с помощью правой кнопки мыши. Он позволяет изменить отображаемое контекстное меню. |
Обработчик наложения значков | Вызывается перед отображением значка файла. Это позволяет указать наложение для значка файла. |
Обработчик поиска | Вызывается для запуска поисковой системы. Она позволяет реализовать пользовательскую поисковую систему, доступную из меню "Пуск" или Обозреватель Windows. |
Сведения о том, как реализовать определенные обработчики расширений, рассматриваются в разделах, перечисленных выше. В оставшейся части этого документа рассматриваются некоторые проблемы реализации, которые являются общими для всех обработчиков расширений оболочки.
- Реализация обработчиков расширений оболочки
- Улучшение Поиска Windows с помощью обработчиков расширений оболочки
- Регистрация обработчиков расширений оболочки
- Связанные темы
Реализация обработчиков расширений оболочки
Большая часть реализации объекта обработчика расширения оболочки зависит от его типа. Однако существуют некоторые общие элементы. В этом разделе рассматриваются аспекты реализации, общие для всех обработчиков расширений оболочки.
Многие обработчики расширений оболочки являются внутрипроцессными объектами модели COM. Им необходимо присвоить идентификатор GUID и зарегистрировать их, как описано в разделе Регистрация обработчиков расширений оболочки. Они реализуются как библиотеки DLL и должны экспортировать следующие стандартные функции:
- DllMain. Стандартная точка входа в библиотеку DLL.
- DllGetClassObject. Предоставляет фабрику классов объекта.
- DllCanUnloadNow. COM вызывает эту функцию, чтобы определить, обслуживает ли объект какие-либо клиенты. В противном случае система может выгрузить библиотеку DLL и освободить связанную память.
Как и все COM-объекты, обработчики расширений оболочки должны реализовывать интерфейс IUnknown и фабрику классов. Большинство обработчиков расширений также должны реализовывать интерфейс IPersistFile или IShellExtInit в Windows XP или более ранней версии. Они были заменены IInitializeWithStream, IInitializeWithItem и IInitializeWithFile в Windows Vista. Оболочка использует эти интерфейсы для инициализации обработчика.
Интерфейс IPersistFile должен быть реализован следующим образом:
- Обработчики данных
- Удаление обработчиков
В прошлом обработчики значков также требовались для реализации IPersistFile, но это уже не так. Для обработчиков значков IPersistFile теперь является необязательным, а другие интерфейсы, такие как IInitializeWithItem , являются предпочтительными.
Интерфейс IShellExtInit должен быть реализован следующим образом:
- Обработчики контекстного меню
- Обработчики перетаскивания
- Обработчики страниц свойств
Реализация IPersistFile
Интерфейс IPersistFile предназначен для загрузки объекта из файла диска или его сохранения в файле диска. В ней есть шесть методов, помимо IUnknown, пять собственных, и метод GetClassID , который он наследует от IPersist. При использовании расширений Оболочки IPersist используется только для инициализации объекта обработчика расширения Оболочки. Так как обычно нет необходимости считывать данные с диска или записывать их на диск, только методы GetClassID и Load требуют реализации nontoken.
Оболочка сначала вызывает GetClassID , а функция возвращает идентификатор класса (CLSID) объекта обработчика расширения. Затем оболочка вызывает Load и передает два значения. Первый, pszFileName, представляет собой строку Юникода с именем файла или папки, с которой будет работать оболочка. Второй — dwMode, который указывает режим доступа к файлу. Так как доступ к файлам обычно не требуется, dwMode обычно равен нулю. Метод сохраняет эти значения по мере необходимости для последующего использования.
В следующем фрагменте кода показано, как типичный обработчик расширения оболочки реализует методы GetClassID и Load . Он предназначен для обработки ANSI или Юникода. CLSID_SampleExtHandler — guid объекта обработчика расширения, а CSampleExtHandler — имя класса, используемого для реализации интерфейса. Переменные m_szFileName и m_dwMode являются частными переменными, которые используются для хранения имени файла и флагов доступа.
wchar_t m_szFileName[MAX_PATH]; // The file name
DWORD m_dwMode; // The file access mode
CSampleExtHandler::GetClassID(CLSID *pCLSID)
{
*pCLSID = CLSID_SampleExtHandler;
}
CSampleExtHandler::Load(PCWSTR pszFile, DWORD dwMode)
{
m_dwMode = dwMode;
return StringCchCopy(_szFileName, ARRAYSIZE(m_szFileName), pszFile);
}
Реализация IShellExtInit
Интерфейс IShellExtInit содержит только один метод , IShellExtInit::Initialize, в дополнение к IUnknown. Метод имеет три параметра, которые оболочка может использовать для передачи информации различных типов. Передаваемые значения зависят от типа обработчика, а для некоторых можно задать значение NULL.
- pIDFolder содержит указатель папки на список идентификаторов элементов (PIDL). Для расширений страниц свойств имеет значение NULL. Для расширений контекстного меню это PIDL папки, которая содержит элемент, контекстное меню которого отображается. Для обработчиков перетаскивания, не являющихся стандартными, это PIDL целевой папки.
- pDataObject содержит указатель на интерфейс IDataObject объекта данных. Объект данных содержит одно или несколько имен файлов в формате CF_HDROP .
- hRegKey содержит раздел реестра для типа файлового объекта или папки.
Метод IShellExtInit::Initialize сохраняет имя файла, указатель IDataObject и раздел реестра при необходимости для последующего использования. В следующем фрагменте кода показана реализация IShellExtInit::Initialize. Для простоты в этом примере предполагается, что объект данных содержит только один файл. Как правило, он может содержать несколько файлов, каждый из которых потребуется извлечь.
LPCITEMIDLIST m_pIDFolder; //The folder's PIDL
wchar_t m_szFile[MAX_PATH]; //The file name
IDataObject *m_pDataObj; //The IDataObject pointer
HKEY m_hRegKey; //The file or folder's registry key
STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
IDataObject *pDataObj,
HKEY hRegKey)
{
// If Initialize has already been called, release the old PIDL
ILFree(m_pIDFolder);
m_pIDFolder = nullptr;
// Store the new PIDL.
if (pIDFolder)
{
m_pIDFolder = ILClone(pIDFolder);
}
// If Initialize has already been called, release the old
// IDataObject pointer.
if (m_pDataObj)
{
m_pDataObj->Release();
}
// If a data object pointer was passed in, save it and
// extract the file name.
if (pDataObj)
{
m_pDataObj = pDataObj;
pDataObj->AddRef();
STGMEDIUM medium;
FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
UINT uCount;
if (SUCCEEDED(m_pDataObj->GetData(&fe, &medium)))
{
// Get the count of files dropped.
uCount = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);
// Get the first file name from the CF_HDROP.
if (uCount)
DragQueryFile((HDROP)medium.hGlobal, 0, m_szFile,
sizeof(m_szFile)/sizeof(TCHAR));
ReleaseStgMedium(&medium);
}
}
// Duplicate the registry handle.
if (hRegKey)
RegOpenKeyEx(hRegKey, nullptr, 0L, MAXIMUM_ALLOWED, &m_hRegKey);
return S_OK;
}
CSampleExtHandler — это имя класса, используемого для реализации интерфейса. Переменные m_pIDFolder, m_pDataObject, m_szFileName и m_hRegKey являются частными переменными, используемыми для хранения передаваемых сведений. Для простоты в этом примере предполагается, что объект данных будет хранить только одно имя файла. После извлечения структуры FORMATETC из объекта данных dragQueryFile используется для извлечения имени файла из элемента medium.hGlobal структуры FORMATETC. Если передается раздел реестра, метод использует RegOpenKeyEx для открытия ключа и назначает дескриптор m_hRegKey.
Настройка подсказки
Существует два способа настройки подсказок:
- Реализуйте объект, поддерживающий IQueryInfo , а затем зарегистрируйте этот объект в соответствующем подразделе в реестре (см. раздел Регистрация обработчиков расширений оболочки ниже).
- Укажите фиксированную строку или список определенных свойств файла, которые будут отображаться.
Чтобы отобразить фиксированную строку для расширения пространства имен, создайте запись с именем InfoTip
в ключе {CLSID} расширения пространства имен. Задайте для этой записи значение либо литеральной строки, которую вы хотите отобразить, как показано в этом примере, либо непрямой строкой, указывающей ресурс и индекс внутри этого ресурса (в целях локализации).
HKEY_CLASSES_ROOT
CLSID
{CLSID}
InfoTip = InfoTip string for your namespace extension
Чтобы отобразить фиксированную строку для типа файла, создайте запись с именем InfoTip
в ключе ProgID этого типа файла. Задайте значение этой записи как литеральную строку, которую требуется отобразить, или непрямую строку, указывающую ресурс и индекс в этом ресурсе (в целях локализации), как показано в этом примере.
HKEY_CLASSES_ROOT
ProgID
InfoTip = Resource.dll, 3
Если вы хотите, чтобы оболочка отображала определенные свойства файла в подсказке для определенного типа файла, создайте запись с именем InfoTip
в ключе ProgID для этого типа файлов. Задайте значение этой записи в виде разделенного точкой с запятой списка канонических имен свойств, пар идентификатора формата (FMTID)/идентификатора свойства (PID) или и того, и другого. Это значение должно начинаться с "prop:", чтобы определить его как строку списка свойств. Если опустить "prop:", значение будет рассматриваться как литеральное значение и отображаться как таковое.
В следующем примере propname является каноническим именем свойства (например, System.Date), а {fmtid}, pid — парой FMTID/PID .
HKEY_CLASSES_ROOT
ProgID
InfoTip = prop:propname;propname;{fmtid},pid;{fmtid},pid
Можно использовать следующие имена свойств:
Имя свойства | Описание | Получено из |
---|---|---|
Автор | Автор документа | PIDSI_AUTHOR |
Заголовок | Название документа | PIDSI_TITLE |
Тема | Сводка по теме | PIDSI_SUBJECT |
Комментировать | Комментарии к документу | свойства PIDSI_COMMENT или папки или драйвера |
PageCount | Количество страниц | PIDSI_PAGECOUNT |
Имя | Понятное имя | Стандартное представление папок |
OriginalLocation | Расположение исходного файла | Папка «Портфель» и «Корзина» |
DateDeleted | Дата удаления файла | Папка корзины |
Тип | Тип файла | Стандартное представление сведений о папке |
Размер | Размер файла | Стандартное представление сведений о папке |
SyncCopyIn | То же, что и OriginalLocation | То же, что и OriginalLocation |
Изменен | Дата последнего изменения | Стандартное представление сведений о папке |
Создание | Дата создания | Стандартное представление сведений о папке |
Осуществляемый доступ | Дата последнего доступа | Стандартное представление сведений о папке |
InFolder | Каталог, содержащий файл | Результаты поиска документов |
Ранг | Качество поиска соответствия | Результаты поиска документов |
FreeSpace | Доступное дисковое пространство | Диски |
NumberOfVisits | Количество посещений | Папка "Избранное" |
Атрибуты | Атрибуты файла | Стандартное представление сведений о папке |
Company | Название организации | PIDDSI_COMPANY |
Категория | Категория документа | PIDDSI_CATEGORY |
Авторские права | Авторские права на сми | PIDMSI_COPYRIGHT |
HTMLInfoTipFile | HTML InfoTip-файл | файл Desktop.ini для папки |
Улучшение Поиска Windows с помощью обработчиков расширений оболочки
Обработчики расширений оболочки можно использовать для улучшения взаимодействия с пользователем, предоставляемого обработчиком протокола Windows Search. Для включения таких улучшений необходимо спроектировать вспомогательный обработчик расширений оболочки для интеграции с обработчиком протокола поиска в качестве источника данных. Сведения о том, как улучшить обработчик протокола Windows Search за счет интеграции с обработчиком расширения оболочки, см. в разделе Добавление значков, предварительных просмотров и контекстных меню. Дополнительные сведения об обработчиках протоколов Windows Search см. в разделе Разработка обработчиков протоколов.
Регистрация обработчиков расширений оболочки
Объект обработчика расширения оболочки должен быть зарегистрирован, прежде чем оболочка сможет его использовать. В этом разделе описано, как зарегистрировать обработчик расширения оболочки.
При создании или изменении обработчика расширения оболочки важно уведомлять систему о том, что вы внесли изменения с помощью SHChangeNotify, указав событие SHCNE_ASSOCCHANGED . Если вы не вызываете SHChangeNotify, изменение может быть не распознано до перезагрузки системы.
Как и для всех COM-объектов, необходимо создать GUID для обработчика с помощью такого средства, как UUIDGEN.exe. Создайте ключ в HKEY_CLASSES_ROOT\CLSID , имя которого является строковой формой GUID. Так как обработчики расширений оболочки являются внутрипроцессными серверами, необходимо создать ключ InProcServer32 в ключе GUID со значением по умолчанию, равным пути библиотеки DLL обработчика. Используйте модель потоков Apartment.
Каждый раз, когда оболочка выполняет действие, которое может включать обработчик расширения оболочки, она проверяет соответствующий раздел реестра. Таким образом, ключ, с помощью которого регистрируется обработчик расширения, определяет, когда он будет вызываться. Например, обычно используется обработчик контекстного меню, вызываемый при отображении контекстного меню для элемента типа файла. В этом случае обработчик должен быть зарегистрирован под ключом ProgID типа файла.
Имена обработчиков
Чтобы включить обработчик расширения оболочки, создайте подраздел с именем подраздела обработчика (см. ниже) в подразделе ShellExлибо ProgID (для типов файлов), либо имя типа объекта оболочки (для предопределенных объектов оболочки).
Например, если вы хотите зарегистрировать обработчик расширений контекстного меню для MyProgram.1, сначала создайте следующий подраздел:
HKEY_CLASSES_ROOT
MyProgram.1
ShellEx
ContextMenuHandlers
Для следующих обработчиков создайте подраздел под ключом "Имя подраздела обработчика", имя которого является строковой версией CLSID расширения оболочки. В ключе имени подраздела обработчика можно зарегистрировать несколько расширений, создав несколько подразделов.
Обработчик | Интерфейс | Имя подраздела обработчика |
---|---|---|
Обработчик контекстного меню | IContextMenu | ContextMenuHandlers |
Обработчик перехватчика копирования | ICopyHook | CopyHookHandlers |
Обработчик действия перетаскивания | IContextMenu | DragDropHandlers |
Обработчик страницы свойств | IShellPropSheetExt | PropertySheetHandlers |
Обработчик поставщика столбцов (не рекомендуется в Windows Vista) | IColumnProvider | ColumnHandlers |
Для следующих обработчиков значением по умолчанию ключа "Имя подраздела обработчика" является строковая версия CLSID расширения оболочки. Для этих обработчиков можно зарегистрировать только одно расширение.
Обработчик | Интерфейс | Имя подраздела обработчика |
---|---|---|
Обработчик данных | Idataobject | DataHandler |
Обработчик удаления | IDropTarget | DropHandler |
Обработчик значков | IExtractIconA/W | IconHandler |
Обработчик изображений | IExtractImage | {BB2E617C-0920-11d1-9A0B-00C04FC2D6C1} |
Обработчик эскизов изображений | IThumbnailProvider | {E357FCCD-A995-4576-B01F-234630154E96} |
Обработчик подсказок | IQueryInfo | {00021500-0000-0000-C000-0000000000046} |
Ссылка на оболочку (ANSI) | IShellLinkA | {000214EE-0000-0000-C000-00000000000046} |
Ссылка на оболочку (ЮНИКОД) | IShellLinkW | {000214F9-0000-0000-C000-0000000000046} |
Структурированное хранилище | IStorage | {00000000B-0000-0000-C000-0000000000046} |
Метаданные | IPropertyStore | PropertyHandler |
Метаданные | IPropertySetStorage (не рекомендуется в Windows Vista) | PropertyHandler |
Закрепление в меню "Пуск" | IStartMenuPinnedList | {a2a9545d-a0c2-42b4-9708-a0b2badd77c8} |
Закрепление на панели задач | {90AA3A4E-1CBA-4233-B8BB-535773D48449} |
Подразделы, указанные для добавления закрепить в меню "Пуск " и "Закрепить на панели задач" в контекстном меню элемента, необходимы только для типов файлов, включающих запись IsShortCut .
Поддержка обработчиков поставщиков столбцов была удалена в Windows Vista. Кроме того, начиная с Windows Vista, IPropertySetStorage является устаревшим в пользу IPropertyStore.
Хотя IExtractImage по-прежнему поддерживается, IThumbnailProvider является предпочтительным для Windows Vista и более поздних версий.
Предопределенные объекты оболочки
Оболочка определяет дополнительные объекты в HKEY_CLASSES_ROOT которые можно расширить так же, как типы файлов. Например, чтобы добавить обработчик страниц свойств для всех файлов, можно зарегистрировать с помощью ключа PropertySheetHandlers .
HKEY_CLASSES_ROOT
*
shellex
PropertySheetHandlers
В следующей таблице приведены различные подразделы HKEY_CLASSES_ROOT , в которых можно зарегистрировать обработчики расширений. Обратите внимание, что многие обработчики расширений не могут быть зарегистрированы во всех перечисленных подразделах. Дополнительные сведения см. в документации по конкретному обработчику.
Подраздел | Описание | Возможные обработчики | Версия |
---|---|---|---|
* | Все файлы | Контекстное меню, страница свойств, глаголы (см. ниже) | Все |
AllFileSystemObjects | Все файлы и папки файлов | Контекстное меню, страница свойств, глаголы | 4,71 |
Папка | Все папки | Контекстное меню, страница свойств, глаголы | Все |
Каталог | Папки файлов | Контекстное меню, страница свойств, глаголы | Все |
Каталог\Фон | Фон папки файлов | Только контекстное меню | 4,71 |
Диске | Все диски в MyComputer, например "C:\" | Контекстное меню, страница свойств, глаголы | Все |
Network | Вся сеть (в разделе Мои сетевые расположения) | Контекстное меню, страница свойств, глаголы | Все |
Network\Type\ # | Все объекты типа # (см. ниже) | Контекстное меню, страница свойств, глаголы | 4,71 |
NetShare | Все сетевые ресурсы | Контекстное меню, страница свойств, глаголы | 4,71 |
NetServer | Все сетевые серверы | Контекстное меню, страница свойств, глаголы | 4,71 |
network_provider_name | Все объекты, предоставляемые поставщиком сети "network_provider_name" | Контекстное меню, страница свойств, глаголы | Все |
принтеры; | Все принтеры | Контекстное меню, страница свойств | Все |
AudioCD | Аудио компакт-диск в CD-дисководе | Только глаголы | Все |
DVD | DVD-накопитель (Windows 2000) | Контекстное меню, страница свойств, глаголы | 4,71 |
Примечания.
- Чтобы открыть контекстное меню фона файловой папки, щелкните правой кнопкой мыши в папке файлов, но не по содержимому папки.
- "Verbs" — это специальные команды, зарегистрированные в HKEY_CLASSES_ROOT\подразделе\Командная команда оболочки\ .
- Длятипа\#сети\ "#" — это код типа сетевого поставщика в десятичном формате. Код типа сетевого поставщика — это высокое слово типа сети. Список типов сети приведен в файле заголовка Winnetwk.h (значения WNNC_NET_*). Например, WNNC_NET_SHIVA 0x00330000, поэтому соответствующий ключ типа будет HKEY_CLASSES_ROOT\тип\сети\51 .
- "network_provider_name" — это имя поставщика сети, указанное в WNetGetProviderName, с пробелами, преобразованными в символы подчеркивания. Например, если установлен поставщик сетевых сетей Майкрософт, его имя поставщика — "Сеть Microsoft Windows", а соответствующий network_provider_name— Microsoft_Windows_Network.
Пример регистрации обработчика расширений
Чтобы включить определенный обработчик, создайте подраздел под ключом типа обработчика расширений с именем обработчика. В оболочке не используется имя обработчика, но оно должно отличаться от всех других имен в подразделе этого типа. Задайте значение по умолчанию подраздела name в строковой форме GUID обработчика.
В следующем примере показаны записи реестра, включающие обработчики контекстного меню и расширений страниц свойств, используя пример типа файла .myp:
HKEY_CLASSES_ROOT
.myp
(Default) = MyProgram.1
CLSID
{00000000-1111-2222-3333-444444444444}
InProcServer32
(Default) = C:\MyDir\MyCommand.dll
ThreadingModel = Apartment
{11111111-2222-3333-4444-555555555555}
InProcServer32
(Default) = C:\MyDir\MyPropSheet.dll
ThreadingModel = Apartment
MyProgram.1
(Default) = MyProgram Application
Shellex
ContextMenuHandler
MyCommand
(Default) = {00000000-1111-2222-3333-444444444444}
PropertySheetHandlers
MyPropSheet
(Default) = {11111111-2222-3333-4444-555555555555}
Процедура регистрации, описанная в этом разделе, должна соблюдаться для всех систем Windows.
Связанные темы