Создание обработчиков расширений оболочки
Возможности оболочки можно расширить с помощью записей реестра и .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 используется только для инициализации объекта обработчика расширений Shell. Так как обычно нет необходимости считывать или записывать данные на диск, только методы GetClassID и Load требуют нетокенной реализации.
Оболочка сначала вызывает GetClassID, а функция возвращает идентификатор класса (CLSID) объекта обработчика расширений. Затем оболочка вызывает Load и передает два значения. Первое, pszFileName, представляет собой строку Юникода с именем файла или папки, с которым должна работать среда Shell. Второй — это 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 используется для извлечения имени файла из элемента FORMATETC структуры medium.hGlobal. Если передан раздел реестра, метод использует RegOpenKeyEx для открытия ключа и присваивания дескриптора m_hRegKey.
Настройка infotip
Существует два способа настройки подсказок.
- Реализуйте объект, поддерживающий 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 или папки или драйвера |
КоличествоСтраниц | Количество страниц | PIDSI_PAGECOUNT |
Имя | Удобочитаемое имя | Стандартное представление папок |
Оригинальное расположение | Расположение исходного файла | Папка портфеля и Корзина |
ДатаУдаления | Дата удаления файла | Папка корзины |
Тип | Тип файла | Представление сведений о стандартной папке |
Размер | Размер файла | Представление сведений о стандартной папке |
SyncCopyIn | То же, что и OriginalLocation | То же, что и OriginalLocation |
Модифицированный | Дата последнего изменения | Представление сведений о стандартной папке |
Создан | Дата создания | Представление сведений о стандартной папке |
Получен доступ | Дата последнего доступа | Представление сведений о стандартной папке |
InFolder | Каталог, содержащий файл | Результаты поиска документов |
Ранг | Качество соответствия поиска | Результаты поиска документов |
Свободное пространство | Доступное место для хранения | Дисководы |
КоличествоПосещений | Количество посещений | Папка избранного |
Атрибуты | Атрибуты файла | Представление сведений о стандартной папке |
Компания | Название компании | PIDDSI_COMPANY |
Категория | Категория документов | PIDDSI_CATEGORY |
Авторское право | Авторские права на медиа | PIDMSI_COPYRIGHT |
HTMLInfoTipFile | HTML InfoTip-файл | Desktop.ini файл для папки |
Улучшение поиска Windows с помощью обработчиков расширений оболочки
Обработчики расширений оболочки могут использоваться для улучшения пользовательского интерфейса, предоставляемого обработчиком протокола Поиска Windows. Чтобы включить такие улучшения, вспомогательный обработчик расширения оболочки должен быть разработан для интеграции с обработчиком поискового протокола в качестве источника данных. Сведения о том, как улучшить обработчик протокола Поиска Windows путем интеграции с обработчиком расширений оболочки, см. в разделе Добавление значков, предварительных просмотров и контекстных меню. Дополнительные сведения об обработчиках протоколов 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-000000000046} |
Ссылка оболочки системы (ANSI) | IShellLinkA | {000214EE-0000-0000-C000-000000000046} |
Ссылка оболочки (Юникод) | IShellLinkW | {000214F9-0000-0000-C000-000000000046} |
Структурированное хранилище | IStorage | {0000000B-0000-0000-C000-000000000046} |
Метаданные | 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, в которых можно зарегистрировать обработчики расширений. Обратите внимание, что многие обработчики расширений не могут быть зарегистрированы во всех перечисленных подразделах. Дополнительные сведения см. в документации конкретного обработчика.
Подраздел | Описание | Возможные обработчики | Версия |
---|---|---|---|
* | Все файлы | Контекстное меню, лист свойств, команды (см. ниже) | Все |
Все объекты файловой системы | Все файлы и папки файлов | Контекстное меню, лист свойств, команды | 4.71 |
папка | Все папки | Контекстное меню, лист свойств, команды | Все |
Директория | Папки файлов | Контекстное меню, лист свойств, команды | Все |
Directory\Background | Фон папки файла | Только контекстное меню | 4.71 |
диск | Все диски в MyComputer, такие как "C:\" | Контекстное меню, лист свойств, команды | Все |
сеть | Вся сеть (в разделе "Мои сетевые места") | Контекстное меню, лист свойств, команды | Все |
Network\Type\# | Все объекты типа # (см. ниже) | Контекстное меню, лист свойств, команды | 4.71 |
NetShare | Все сетевые общие ресурсы | Контекстное меню, лист свойств, команды | 4.71 |
NetServer | Все сетевые серверы | Контекстное меню, лист свойств, команды | 4.71 |
network_provider_name | Все объекты, предоставляемые поставщиком сети "network_provider_name" | Контекстное меню, лист свойств, команды | Все |
принтеры | Все принтеры | Контекстное меню, лист свойств | Все |
Аудио CD | Аудио CD в CD-приводе | Только глаголы | Все |
DVD | DVD-диск (Windows 2000) | Контекстное меню, лист свойств, команды | 4.71 |
Примечания:
- Контекстное меню папки с файлами вызывается щелчком правой кнопки мыши внутри папки, но не по содержимому папки.
- "Глаголы" — это специальные команды, зарегистрированные в разделе HKEY_CLASSES_ROOT\Подраздел\Shell\Глагол.
- Для сети и типа\\#, символ "#" — это код типа поставщика сети в десятичной системе. Код типа поставщика сети — это старшее слово типа сети. Список типов сети представлен в файле заголовка Winnetwk.h (значения WNNC_NET_*). Например, WNNC_NET_SHIVA имеет значение 0x00330000, поэтому соответствующий ключ типа будет HKEY_CLASSES_ROOT\Network\Type\51.
- "network_provider_name" — это имя поставщика сети, указанное WNetGetProviderNameс пробелами, преобразованными в символы подчеркивания. Например, если установлен поставщик сети Microsoft Network, его имя — Microsoft Windows Network, а соответствующий network_provider_name — Microsoft_Windows_Network.
Пример регистрации обработчика расширений
Чтобы включить конкретный обработчик, создайте подраздел под ключом типа обработчика расширений с именем обработчика. Оболочка не использует имя обработчика, но оно должно отличаться от всех остальных имен в подразделе данного типа. Установите значение по умолчанию для подключа с именем на строковую форму 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.
Связанные разделы