Что такое общая библиотека оболочки Windows

Обновлено: 29.06.2024

В этом разделе описывается введение библиотек для Windows 7 и более поздних версий. Библиотеки — это функция оболочки Windows. Чтобы получить доступ к функциям оболочки Windows, таким как библиотеки, сторонние разработчики приложений Windows Search должны сначала внедрить хранилище данных оболочки. Дополнительные сведения см. в разделе Реализация базовых интерфейсов объектов папок.

Эта тема организована следующим образом:

Библиотеки

В Windows 7 и более поздних версиях библиотеки являются хранилищем пользовательских данных по умолчанию. Пользователи могут просматривать свои файлы так же, как в папке, или они могут просматривать свои файлы, упорядоченные по таким свойствам, как дата, тип и автор. В отличие от папки библиотека фактически не хранит элементы, а отображает файлы, которые хранятся в нескольких папках одновременно. Библиотеки предоставляют единую точку доступа, а расширенные обзоры позволяют пользователям их агрегированного контента. Например, если у пользователя есть музыкальные файлы в папках на внешнем диске в дополнение к папке «Моя музыка», то он может сразу получить доступ ко всем музыкальным файлам через музыкальную библиотеку.

Точки ввода пользовательских данных

Библиотеки по умолчанию (например, «Мои документы», «Мои изображения» и т. д.) эквивалентны известной папке. Библиотеки по умолчанию предоставляют знакомые точки входа для пользователей, но, поскольку содержимое библиотек не ограничивается содержимым известных папок, библиотеки предоставляют пользователям больше свободы в определении того, где должны храниться документы и мультимедиа. Библиотеки доступны через пространство имен Shell (источник данных Shell). Ваше приложение может предоставить пользователям те же знакомые точки входа в их данные, включив поддержку библиотеки и просмотр.

Наборы папок

Библиотеки — это пользовательские наборы контента. Windows Search индексирует поддерживаемые папки, когда они включены в библиотеки. Это обеспечивает мгновенный поиск и просмотры стека на основе свойств в библиотеках.

Поддерживаемые папки в библиотеках

Для поддержки папок в библиотеках они должны индексироваться на локальном компьютере и индексироваться либо на удаленном компьютере Windows, либо индексироваться на сервере с файлами, проиндексированными Windows Search.

Добавление неподдерживаемых папок пользователями в диалоговом окне управления библиотекой Windows заблокировано. Если неиндексированные удаленные папки добавляются в библиотеку с помощью IShellLibrary API, пользовательский интерфейс библиотеки вернется к безопасному режиму библиотеки. В безопасном режиме из затронутой библиотеки удаляются такие функции, как представления упорядочения стека на основе свойств, предложения фильтров и поддержка поиска в меню «Пуск».

В следующей таблице перечислены папки, включенные в библиотеки с помощью диалогового окна управления библиотекой проводника Windows, а также папки, которые не поддерживаются в безопасном режиме:

< td>Другие источники данных (такие как Microsoft SharePoint, Microsoft Exchange, Microsoft OneDrive и т. д.)
Поддерживаемые папки Неподдерживаемые папки
Фиксированные и внешние NTFS и FAT32 жесткие диски Съемные диски (например, флэш-накопители и SD-карты)
Общие ресурсы, индексируемые Windows Search (например, серверы отделов и компьютеры, на которых Windows 10 и Windows 7 Home edition) Съемные носители (например, компакт-диски и DVD-диски)
Общие ресурсы, доступные в автономном режиме (например, перенаправленные мои документы , кэш на стороне клиента) Общие сетевые ресурсы, которые недоступны в автономном режиме или удаленно индексированы (например, диски NAS)
н/д

Хранилище

Библиотеки — это наборы папок для хранения. Пользователи могут сохранять и копировать файлы в библиотеку напрямую, поскольку у каждой библиотеки есть место сохранения по умолчанию для отправки этих файлов. Для библиотек по умолчанию это известная пользователю папка, включенная в библиотеку (например, «Мои документы»), или первая папка, добавленная в пользовательскую библиотеку. Это папка, в которую помещаются файлы, когда пользователь перетаскивает файлы в библиотеку или сохраняет в библиотеку с помощью общего диалогового окна файлов. Пользователь может изменить место сохранения библиотеки по умолчанию в любой момент, но если он удалит место сохранения по умолчанию, в качестве нового места сохранения будет выбрана следующая папка в библиотеке. Пользователи могут дополнительно сохранять файлы в любую папку, на которую у них есть права доступа, которая была включена в библиотеку.

Контейнеры оболочки, не относящиеся к файловой системе

Библиотеки могут содержать контейнеры оболочки файловой системы, такие как «Компьютер» и «Панель управления», но содержать элементы файловой системы. Папки и содержимое библиотеки можно перечислять и получать к ним доступ с помощью API для файлов и папок файловой системы в предыдущих операционных системах. Если ваше приложение сильно зависит от конкретных API-интерфейсов файловой системы, то API-интерфейс IShellLibrary можно использовать для получения путей файловой системы к папкам и файлам в библиотеках. В большинстве случаев рекомендуется использовать модель программирования Shell для поддержки нескольких версий Windows и гибкости элементов.Дополнительные сведения см. в разделе Навигация по пространству имен оболочки.

Описания библиотеки

Описания библиотек сохраняются на диске в виде XML-файла в папке %appdata%Microsoft\Windows\Libraries (и, возможно, как FOLDERID_Libraries. Дополнительные сведения о FOLDERID_Libraries см. в KNOWNFOLDERID.

Файлы описания библиотеки представляют собой XML-файлы с расширением имени файла .library-ms. Эти файлы никогда не должны открываться или редактироваться приложениями. Текст пути к папке, сохраняемый в файлах описания библиотеки, не всегда актуален. Папки библиотеки сохраняются в файле описания библиотеки в сериализованном двоичном формате Shell Links. Дополнительные сведения о библиотеках и схеме описания библиотеки см. в разделе Схема описания библиотеки. Дополнительные сведения о федеративных соединителях поиска и схеме описания соединителя поиска см. в разделе Схема описания соединителя поиска.

[ПРИМЕЧАНИЕ]
Приложения должны всегда использовать модель программирования Shell или API IShellLibrary для использования и управления содержимым библиотеки и никогда не пытаться вручную получить доступ к файлу описания библиотеки или изменить его.

< /цитата>

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

Обзор программирования библиотеки

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

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

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

Программирование с библиотеками

Модель программирования оболочки Windows описывает, как программа взаимодействует с программными объектами оболочки Windows. Хотя объекты файловой системы, такие как файлы и каталоги, представлены объектами оболочки Windows, не все объекты оболочки Windows представлены файловой системой. Библиотеки, например, являются объектами оболочки Windows, не имеющими эквивалента в файловой системе. Использование объектов оболочки Windows в вашей программе позволяет вашей программе получать доступ ко всем объектам оболочки, а не только к объектам файловой системы.

Для достижения наилучших результатов ваша программа будет использовать API библиотеки оболочки для взаимодействия с библиотеками и доступа к их содержимому. Хотя библиотеки содержат элементы файловой системы, такие как папки и файлы, библиотеки не являются элементами файловой системы. Таким образом, API файловой системы нельзя использовать для доступа к функциям или содержимому библиотеки.

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

Переход из известных папок в библиотеки

До Windows 7 было обычным делом использовать известную папку, например папку «Мои документы», в качестве папки по умолчанию при сохранении или открытии файлов. В Windows 7 следует использовать соответствующую библиотеку, чтобы пользователь мог работать с вашей программой так же, как и с другими программами Windows 7, такими как Проводник Windows.

Если в настоящее время вы используете API оболочки Windows в своей программе, добавить поддержку библиотек несложно. Например, если вы в настоящее время вызываете функцию SHGetKnownFolderItem для получения местоположения папки «Мои документы», вы можете заменить значение KNOWNFOLDERID известной папки «Мои документы» значением KNOWNFOLDERID соответствующей библиотеки.

В следующей таблице показано соотношение между значениями KNOWNFOLDERID известных папок и значением KNOWNFOLDERID соответствующей библиотеки в Windows 7.

Значения KNOWNFOLDERID известной папки Значения KNOWNFOLDERID библиотеки
FOLDERID_Documents FOLDERID_DocumentsLibrary
FOLDERID_Pictures FOLDERID_PicturesLibrary
FOLDERID_Music FOLDERID_MusicLibrary
FOLDERID_RecordedTV FOLDERID_RecordedTVLibrary

Домашняя группа и общие библиотеки

Добавление поддержки библиотек в вашу программу активирует поддержку общих библиотек в домашней группе. Домашняя группа идентифицируется своим значением KNOWNFOLDERID FOLDERID_HomeGroup. Ваша программа может определить частное или общее местоположение пользователя по умолчанию для сохранения, установив значение DEFAULTSAVEFOLDERTYPE в вызове метода IShellLibrary::GetDefaultSaveFolder.

Использование общего диалогового окна файла с библиотеками

Использование диалогового окна общего файла с библиотеками Диалоговое окно общего файла было обновлено для поддержки библиотек в Windows 7. На следующем рисунке показано, как диалоговое окно общего файла отображается для пользователя в Windows 7.

снимок экрана диалоговое окно общего файла, показывающее библиотеки

В Windows 7, если ваша программа в настоящее время отображает обычное диалоговое окно файла и не изменяет шаблон диалогового окна и не перехватывает какие-либо его события, она автоматически отобразит новую версию диалогового окна Windows 7. В частности, при вызове функции диалогового окна общего файла элементы lpfnHook, hInstance, lpTemplatename структуры OPENFILENAME должны иметь значение NULL, а флаги OFN_ENABLEHOOK и OFN_ENABLETEMPLATE должны быть сняты.

В Windows 7 интерфейсы, связанные с IFileDialog, заменяют стандартные функции диалогового окна файлов, которые использовались в более ранних версиях Windows. Более ранние общие функции диалогового окна файла по-прежнему поддерживаются в Windows 7, но они не обеспечивают полного пользовательского интерфейса Windows 7 и не поддерживают библиотеки. Некоторые из новых функций, поддерживаемых интерфейсами, связанными с IFileDialog, включают:

  • Пользователь может получить доступ к свойствам файла, поддерживаемым проводником Windows 7, для поиска и выбора файлов.
  • Программа может использовать интерфейсы и методы из API пространства имен Shell для работы с элементами.
  • Программа может использовать модель настройки на основе данных вместо модели настройки на основе файлов ресурсов для добавления новых элементов управления в общие диалоговые окна файлов.

Вы должны использовать интерфейсы, связанные с IFileDialog, когда:

  • вам необходимо настроить общее диалоговое окно файла для вашей программы в Windows 7. Это позволит вашей программе работать с библиотеками и поддерживать настройку вашего диалогового окна.
  • вы хотите, чтобы пользователь мог выбирать несколько файлов в общем диалоговом окне файлов. Это гарантирует, что вы получите правильные пути к выбранному объекту, поскольку содержимое библиотеки может храниться в разных папках.

Для получения дополнительной информации об интерфейсах, связанных с IFileDialog, см.:

Включение выбора библиотеки из пользовательского интерфейса

Если ваша программа позволяет пользователю выбирать папку, например, для функций импорта или экспорта в Windows 7, она также должна позволять пользователю выбирать библиотеку. Интерфейс IFileOpenDialog и функция SHBrowseForFolder позволяют пользователю выбрать библиотеку при появлении запроса на выбор папки. Интерфейс IFileOpenDialog предпочтительнее функции SHBrowseForFolder, поскольку IFileOpenDialog поддерживает пользовательский интерфейс Windows 7.

Чтобы разрешить пользователям выбирать папки при использовании интерфейса IFileOpenDialog, вызовите SetOptions с установленным флагом FOS_PICKFOLDERS и убедитесь, что флаг FOS_FORCEFILESYSTEM снят.

Чтобы разрешить пользователям выбирать папки при вызове функции SHBrowseForFolder, в элементе ulFlags структуры BROWSEINFO установите флаг BIF_USENEWUI и снимите флаг BIF_RETURNONLYFSDIRS.

Доступ к содержимому библиотеки в программе

Для доступа к содержимому библиотеки необходимо использовать API оболочки Windows. Функции API файловой системы нельзя использовать для доступа к содержимому библиотеки, поскольку библиотеки не являются объектами файловой системы. Если ваша программа использует пользовательский файловый браузер, основанный на API файловой системы, она не сможет просматривать библиотеки или получать доступ к их содержимому.

В этом разделе описывается, как получить доступ к содержимому библиотеки, чтобы выбрать лучший способ обновления программы для работы с библиотеками.

Доступ к содержимому библиотеки с помощью интерфейса IShellLibrary

Самый простой способ для программы получить доступ к содержимому библиотеки — использовать Shell Library API. Если вы работаете над программой, использующей API файловой системы, API библиотеки оболочки может возвращать папки файловой системы библиотеки, что сводит к минимуму изменения в существующем программном коде.

Доступ к содержимому библиотеки с помощью Shell API

Поскольку объекты библиотеки являются частью модели программирования оболочки, их можно использовать с другими API-интерфейсами оболочки Windows. Например, вы можете использовать интерфейсы IShellItem и IShellFolder в своей программе вместе с соответствующими вспомогательными функциями для доступа к содержимому библиотеки таким же образом, как если бы вы перечисляли папки и содержимое папок для доступа к содержимому с помощью API-интерфейсов файловой системы.

API оболочки Windows поддерживают два режима перечисления для доступа к содержимому библиотеки:

Просмотреть перечисление

Перечисление просмотра — это режим перечисления по умолчанию, в котором перечисляется содержимое папки библиотеки. Снимите флаг SHCONTF_NAVIGATION_ENUM, чтобы использовать этот режим.

Перечисление навигации

Перечисление навигации перечисляет папки библиотеки. Установите флаг SHCONTF_NAVIGATION_ENUM, чтобы использовать этот режим.

Если ваша программа использует настраиваемый элемент управления деревом для навигации по папкам пользователя, перечисление папок в режиме перечисления навигации даст вам список папок библиотеки, соответствующий тому, как Проводник Windows перечисляет папки в Windows 7.

Примеры использования этих функций в программе см. в образце ShellStorage в Windows SDK.

Сохранение пользовательского контента в библиотеке

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

В каждой библиотеке есть папка, которая назначается местом сохранения по умолчанию. Место сохранения по умолчанию определяется при создании библиотеки; однако пользователь может изменить место сохранения по умолчанию на любую папку в библиотеке. Хотя пользователю не нужно настраивать место сохранения по умолчанию, у него есть возможность изменить его. Если пользователь удалит папку, которая в данный момент установлена ​​в качестве места сохранения по умолчанию, библиотека автоматически настроит следующую папку в библиотеке в качестве места сохранения по умолчанию.

Существует несколько способов сохранения пользовательского контента в библиотеке.

API оболочки

Если вы используете модель программирования оболочки и сохраняете элемент оболочки, представленный IShellItem, IStorage или IStream, в библиотечный объект, элемент оболочки будет автоматически сохранен в месте сохранения по умолчанию в библиотеке.< /p>

API файловой системы

Если у вас есть программа, использующая множество вызовов API файловой системы, вы можете получить путь к папке, которая определена как место сохранения библиотеки по умолчанию. Затем путь к папке можно передать в API файловой системы.

Примеры использования этих функций в программе см. в образце ShellStorage в Windows SDK.

Поддержка операций перетаскивания в библиотеке

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

Примеры того, как добавить поддержку библиотек для функций перетаскивания ваших программ, см. в образце ShellLibraryCommandLine в Windows SDK.

Синхронизация с библиотекой

В этом разделе описывается, как программа может обновлять представление содержимого библиотеки.

Массовое обновление

Поскольку пользователь может изменять папки библиотеки в интерактивном режиме, когда ваша программа не запущена, ваша программа должна вызывать SHResolveLibrary, когда она начинает обнаруживать и сохранять любые изменения в библиотеке. Shell API предоставляет функцию SHResolveLibrary, позволяющую программе получать текущее содержимое библиотеки и текущее расположение любых папок, которые могут содержаться в библиотеке.

Обратите внимание, что SHResolveLibrary — это блокирующая функция, для возврата которой может потребоваться много времени в зависимости от того, что изменилось в библиотеке. Поэтому его не следует вызывать из потока пользовательского интерфейса.

После обновления программы она может зарегистрироваться для получения уведомлений об изменениях, чтобы сохранить текущее представление.

Уведомление Shell API

API оболочки Windows предоставляет функцию SCHhangeNotifyRegister, которая является предпочтительным способом уведомления неслужебных процессов об изменении в библиотеке.

Чтобы обнаруживать изменения элементов в библиотеке с помощью API оболочки Windows, вызовите SHhangeNotifyRegister, чтобы зарегистрировать вашу программу для получения уведомлений об изменениях элементов в папке библиотеки. Эта функция может уведомить вашу программу, если есть изменения в какой-либо библиотеке или только в определенной библиотеке. Уведомления отправляются немедленно при изменении библиотеки.

Уведомление API файловой системы

Уведомления файловой системы должны использоваться в сервисных процессах.

Чтобы обнаружить изменения элементов в библиотеке с помощью API файловой системы, перечислите папки в библиотеке и вызовите FindFirstChangeNotification для каждой папки, которую нужно отслеживать. Ваша программа получит уведомление, когда отслеживаемая папка изменится. Чтобы найти конкретный файл файлов, которые были изменены в папке, вызовите ReadDirectoryChangesW. Чтобы обнаружить изменения в файле описания библиотеки, отслеживайте папку, в которой он находится. Файл описания библиотеки находится в папке FOLDERID_Libraries. Однако файл описания библиотеки не следует открывать или изменять.


Те из нас, кто использует Windows с первых дней, вероятно, все еще хорошо знакомы с навигацией в ОС без мыши и без сенсорного экрана! Многие люди по-прежнему знают, как перемещаться по командной строке, но это не всегда полезно или целесообразно в зависимости от того, куда вам нужно перейти. Как и во всем, что связано с Microsoft, у нас есть множество способов добраться туда, куда нам нужно, если мы знаем хитрости: команды оболочки. У команд оболочки есть несколько функций, но в основном они используются как ярлыки для определенных папок.

Например, мы можем запустить «shell:downloads», и это откроет новое окно проводника, показывающее папку «Загрузки» текущего пользователя. Точно так же мы можем запустить «shell:windows», и это откроет новое окно с папкой C:\Windows\. В зависимости от ваших предпочтений, вам может показаться, что это легче запомнить, чем «%WinDir%», который также приведет вас к той же папке.

Команды оболочки можно запускать несколькими способами. Их можно просто ввести в командной строке (Win + R) и ввести в адресную строку проводника Windows. Если вам нравятся CMD и PowerShell, вы также можете запустить их там. Если вы находитесь в любой консоли, просто предварите команду оболочки словом «explorer», например: «explorer shell:RecycleBinFolder».

Помимо навигации, некоторые из этих команд имеют реальное практическое назначение. Например, «оболочка: общий рабочий стол» или «оболочка: общий запуск» приведет вас к общедоступному рабочему столу и общедоступным папкам автозагрузки соответственно. Все, что вы поместите в папку рабочего стола, будет отображаться на рабочем столе каждого пользователя, а все, что вы поместите в папку автозагрузки, запустится, когда любой пользователь войдет в систему.

Хотите попробовать команду оболочки следующего уровня? Попробуйте использовать следующий «чит-код» для основной панели управления Windows, или, как его называют в Интернете, «режим бога»:

Откроется окно со многими элементами панели управления в виде списка, упорядоченными по категориям. Это очень удобный способ увидеть практически все доступные варианты.

Вы также можете создать ярлык для главной панели управления Windows, просто создав папку на рабочем столе и назвав ее «GodMode».

Я не буду вдаваться в подробности каждой команды оболочки и вариантов их использования, но рекомендую каждому поклоннику Windows попытаться выучить и запомнить некоторые из них. Они сэкономят ваше время, особенно если вы много работаете в Проводнике. См. следующий список всех команд оболочки:

Расширения оболочки — это мощный и гибкий способ расширить возможности оболочки Windows. Однако при работе с обработчиками расширения Shell вы можете столкнуться со скрытыми трудностями.

В этой статье мы описываем общий подход к созданию расширений оболочки Windows на примере контекстного меню и обработчиков наложения значков. Мы также объясняем ряд ловушек, с которыми вы можете столкнуться при разработке таких типов расширений, и предлагаем несколько рекомендаций, как их избежать.

apriorit

Команда разработчиков драйверов

Содержание:

Что такое расширения оболочки?

Что такое расширение оболочки? Чтобы определить расширения оболочки, давайте рассмотрим обработчик расширений оболочки Windows, который позволяет расширить обычный набор действий при работе с проводником Windows. Расширения оболочки могут быть представлены в виде отдельных плагинов к проводнику Windows. Их можно использовать для добавления новой вкладки в окно свойств, изменения предварительного просмотра файла и других действий.

Прежде чем предпринимать какие-либо действия, командная консоль вызывает зарегистрированные обработчики расширений, чтобы настроить это действие. Типичным примером такой настройки является обработчик расширения Shell для контекстного меню.

В зависимости от типа файла обработчики расширений оболочки могут быть добавлены либо ко всем типам объектов в проводнике Windows, либо только к определенным типам объектов.

Обработчики расширений оболочки, используемые с определенными типами файлов:

 Обработчики расширений оболочки, используемые с определенными типами файлов

Обработчики расширений оболочки, не зависящие от типа файла:

 Обработчики расширений оболочки, которые не зависят от тип файла

Однако независимо от того, к какому типу файлов вы применяете обработчик, использование расширений оболочки может замедлить работу проводника Windows. Помимо Проводника Windows, другие программы, включая Dropbox, TortoiseSVN, WinRAR и SkyDrive, устанавливают свои собственные наборы расширений оболочки.

Создание обработчиков расширения оболочки

В этом разделе мы обсудим процесс создания обработчиков расширений Windows Shell на примере расширений наложения и контекстного меню. Другие типы расширений оболочки могут быть реализованы аналогичным образом.

Каждый обработчик расширения оболочки является объектом объектной модели компонентов (COM). Обработчики должны иметь свой собственный глобальный уникальный идентификатор (GUID) и быть зарегистрированы, прежде чем оболочка сможет их использовать. Путь реестра определяется типом обработчика расширения. Теперь пройдемся по всем этапам создания обработчика расширения Shell.

Реализация необходимых функций и интерфейсов

Поскольку обработчик расширения оболочки является COM-объектом, он реализован в виде библиотеки динамической компоновки (DLL). При этом, как и любой COM-объект, DLL должна экспортировать следующие стандартные функции:

    – Создает точку входа в DLL – Получает объект с помощью фабрики классов – Перед выгрузкой вызывает DLL, чтобы проверить, используется ли она в данный момент – Регистрирует COM-объект в реестре – Удаляет запись COM-объекта из реестра

ClassFactory используется для создания объекта компонента и должен реализовывать интерфейс IClassFactory. Вот как выглядит ClassFactory:

Кроме того, класс, инкапсулирующий логику обработчика расширения, должен реализовывать интерфейс IUnknown, как и все COM-объекты. Интерфейсы, характерные для различных типов расширений оболочки, наследуются от этого интерфейса. Интерфейс IUnknown выглядит следующим образом:

Обратите внимание, что несколько обработчиков расширений могут быть реализованы в одной библиотеке DLL. При этом необходимо указать GUID, выполнить регистрацию в реестре и настроить ClassFactory для каждого обработчика (хотя можно использовать общую ClassFactory для нескольких обработчиков расширений).

Определение интерфейсов для расширений оболочки

Помимо обязательного COM-интерфейса IUnknown, классы расширений должны реализовывать интерфейс, специфичный для расширений Shell. Для разных типов расширений существуют разные наборы необходимых интерфейсов.

Большинство обработчиков расширений также должны реализовывать интерфейс IPersistFile или IShellExtInit в Windows XP или более ранних версиях. Они были заменены на IInitializeWithStream, IInitializeWithItem и IInitializeWithFile в Windows Vista. Оболочка использует эти интерфейсы для инициализации обработчика.

Для обработчика контекстного меню используются интерфейсы IShellExtInit и IContextMenu, а для обработчика значка наложения — интерфейс IShellIconOverlayIdentifier. Давайте рассмотрим каждый из них поближе.

Интерфейс IShellExtInit предоставляет только функцию инициализации обработчика расширения:

Метод Initialize вызывается проводником Windows перед выполнением действия, расширяемого этим обработчиком. Например, в случае расширения контекстного меню этот метод будет вызываться после нажатия на выбранные файлы и до открытия контекстного меню.

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

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

Интерфейс IContextMenu содержит методы для работы с контекстным меню:

Метод QueryContextMenu отвечает за добавление новых пунктов меню в контекстное меню. Здесь вы можете добавить логику для создания новых пунктов меню. Пункт меню может быть создан функцией WinApi InsertMenuItem.

Каждый пункт меню связан со своим идентификатором. Параметр idCmdFirst — это минимальное значение идентификатора, которое может быть присвоено элементу меню. Соответственно, idCmdLast — это максимальное значение идентификатора. Важно, чтобы, если элемент меню содержит подменю, элементам подменю присваивались идентификаторы, созданные после идентификатора пункта меню.

Метод QueryContextMenu возвращает разницу между первым и последним назначенным идентификатором плюс 1.

QueryContextMenu вызывается проводником Windows, только если расширение зарегистрировано для отдельных типов файлов.

Метод InvokeCommand обрабатывает нажатия на добавленные пункты меню.Каждая кнопка меню идентифицируется значением verb, которое указывается при создании элемента в QueryContextMenu . Глагол — это строка с именем команды, которая выполняется пунктом меню. Глагол дается в двух вариантах: с использованием Юникода и без него. Поэтому формат verb следует проверять перед выполнением команды.

Метод GetCommandString используется для получения канонического имени глагола, назначенного элементу меню. Этот метод является необязательным и установлен для Windows XP и более ранних версий Windows. Используется для отображения текста подсказки для выбранного пункта меню в строке состояния.

Этот интерфейс должен быть реализован обработчиком значка наложения:

Метод GetOverlayInfo используется для первого вызова обработчика наложения, чтобы добавить значок в системный список изображений. После этого иконку изменить нельзя, а последующие вызовы GetOverlayInfo должны возвращать путь к файлу, содержащему иконку, и индекс значка. Индекс значка — это порядковый номер значка (начиная с 0) в списке ресурсов DLL.

Если метод возвращает ошибку при первом запуске, значок не будет загружен, даже если последующие вызовы GetOverlayInfo будут успешными. Это может привести к ситуации, когда обработчик работает, а значок не отображается.

Метод GetPriority используется для указания приоритета значка наложения по сравнению с другими значками. В зависимости от этого обработчик может быть либо приоритетным, либо нет. Наивысший приоритет равен 0.

Метод IsMemberOf должен содержать логику, указывающую, следует ли применять значок к данному объекту в проводнике Windows. Этот метод вызывается по очереди для всех объектов в текущем окне проводника Windows при открытии окна и после его обновления. Если вы не укажете здесь никаких фильтров и просто вернете S_OK, значок будет отображаться на всех объектах в проводнике Windows.

Регистрация расширений оболочки

Логика регистрации расширений оболочки Windows должна быть реализована в функции DllRegisterServer. Эта функция вызывается при установке расширения Shell и отвечает за регистрацию COM-объекта. Соответственно функция DllUnregisterServer должна содержать код для удаления записей из реестра.

Обратите внимание, что вы можете получить ошибку 0x80070005 при попытке зарегистрировать DLL в Windows XP или Windows Server 2003. Это происходит потому, что их строгие схемы безопасности позволяют инициировать регистрацию DLL только администраторам.

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

Параметр может быть определен:

  • Для файлов определенного типа: BMP, DOCX, PNG
  • Для всех типов файлов: *
  • Для группы объектов: "Диск", "Каталог", "Папка", "Расположение библиотеки".

Обработчик контекстного меню должен быть зарегистрирован отдельно для каждого типа объекта.

Обработчик наложения значков регистрируется один раз, используя путь:

Кроме того, необходимо зарегистрировать сам COM-компонент:

Например, функция DllRegisterServer, которая регистрирует обработчики значков наложения и обработчики контекстного меню для всех типов файлов ("*"), может выглядеть следующим образом:

Функции RegisterInprocServer , RegisterShellExtContextMenuHandler и RegisterShellExtOverlayIconHandler содержат код для добавления новых кустов и ключей в реестр.

Подготовка ресурсов для обработчиков наложения значков

Значки должны быть подготовлены для правильного отображения обработчиками расширений оболочки.

Для контекстного меню нам нужно изображение в формате BMP. Обработчики наложений немного сложнее: значок должен быть в формате ICO и поддерживать следующие размеры:

  • 10 x 10 (для 16 x 16)
  • 16 x 16 (для 32 x 32)
  • 24 x 24 (для 48 x 48)
  • 128 x 128 (для 256 x 256)

Значки обработчика наложения будут отображаться в левом нижнем углу основного значка и должны занимать не более 25 % значка файла (за исключением 10 x 10 для 16 x 16).

При масштабировании объектов в проводнике Windows правильный размер определяется автоматически.

Установка расширений оболочки

Расширения оболочки устанавливаются с помощью стандартной утилиты Regsvr32. Например:

При выполнении этой команды вызывается функция DllRegisterServer, которая обеспечивает регистрацию расширения в реестре. Вся логика добавления и удаления записей из реестра должна быть реализована разработчиком.

После этого сразу начинает свою работу обработчик контекстного меню, в чем можно убедиться, открыв меню. Что касается обработчика оверлея, то иконки не появятся сразу после регистрации. Чтобы загрузить необходимые ресурсы, необходимо перезапустить проводник Windows.

Удаление расширений оболочки

Для удаления расширения оболочки можно использовать тот же подход, что и для его установки, а именно Regsvr32:

Тем временем, когда мы вызываем функцию DllUnregisterServer, система удаляет записи из реестра.

После удаления обработчика наложения вам также потребуется перезапустить проводник Windows.

Распространенные проблемы и их решения

Вы можете столкнуться с некоторыми проблемами расширения оболочки Windows при написании обработчиков расширений оболочки. Некоторые из этих проблем перечислены ниже вместе с способами их решения:

1. Значки наложения не отображаются

Проблема: как описано выше, эта проблема может заключаться в логике функции GetOverlayInfo. Кроме того, поскольку Windows использует только ограниченное количество зарегистрированных обработчиков значков наложения, все остальные обработчики просто игнорируются.

Список обработчиков, которые не будут игнорироваться, определяется именем в ветке реестра: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers. Система принимает первые 15 обработчиков значков наложения в алфавитном порядке. Поэтому, если в системе установлены Dropbox или TortoiseSVN, которые фиксируют ряд расширений, они могут стать причиной не отображения значков.

Как решить эту проблему: добавьте любой символ перед именем обработчика оверлея во время регистрации. В результате расширение появится в верхней части списка расширений. Например, вы можете добавить пробелы перед именем обработчика.

 Изменение имен обработчиков

2. Проблемы с отображением значков с прозрачным фоном в контекстном меню

Проблема заключается в использовании изображения BMP, которое не поддерживает прозрачность, при добавлении нового пункта меню. Если вы используете файлы ICO или PNG, то после конвертации иконка будет отображаться на черном фоне.

Как это решить: Перерисовать ICO в формат BMP в коде во время работы расширения. Например, можно использовать следующую реализацию (с UX-THEME.DLL):

3. Проблемы с отображением контекстного меню

Может быть несколько проблем, связанных с контекстным меню.

Проблема: после регистрации расширения оболочки для LibraryLocation расширение контекстного меню не отображается.

Проблема может заключаться в реализации метода Initialize в интерфейсе IShellExtInit, который вызывается для инициализации расширения Shell. IdataObject, который используется для получения объектов, для которых будет отображаться расширение, передается в метод Initialize в качестве параметра. Поэтому при нажатии на папки библиотеки (Документы, Музыка и т.д.) любые попытки получить из нее объекты формата CF_HDROP не приводят к ожидаемому результату.

Как решить эту проблему: используйте формат CFSTR_SHELLIDLIST, который похож на CF_HDROP, но содержит PIDL (указатель на идентификатор объекта в структуре оболочки ITEMIDLIST) вместо пути к файлу. Это позволяет CFSTR_SHELLIDLIST обрабатывать объекты системы и виртуальной файловой системы.

Проблема: при регистрации расширения оболочки для AllFileSystemObjects щелчок по файлам .lnk дважды добавляет это расширение оболочки Windows в контекстное меню.

Проблема в том, что расширение работает и для объекта, и для ссылки, которая на него указывает.

Как решить эту проблему: в методе QueryContextMenu интерфейса IContextMenu не только должен быть установлен флаг CMF_DEFAULTONLY, но и расширения контекстного меню должны игнорировать объекты с флагами CMF_NOVERBS и CMF_VERBSONLY.

Проблема: Расширение контекстного меню не отображается для некоторых типов файлов, хотя его можно зарегистрировать для всех типов.

Проблема может заключаться в реализации метода QueryContextMenu интерфейса IcontextMenu. В случае успешной реализации он должен вернуть HRESULT с кодовым значением, равным максимальному смещению назначенного идентификатора команды плюс один.

Например, если idCmdFirst равно 5 и были добавлены еще 3 пункта меню с идентификаторами команд 5, 7 и 8, то возвращаемое значение должно быть таким: MAKE_HRESULT(SEVERITY_SUCCESS, 0, 8 - 5 + 1).

Если вы забудете добавить его, расширение контекстного меню все равно будет работать, но не во всех случаях.

Как решить проблему: убедитесь, что метод QueryContextMenu интерфейса IcontextMenu успешно реализован.

4. Проблема с запуском потока из DllMain

Проблема: при запуске потока в DllMain (например, для инициализации чего-либо) могут возникнуть проблемы с выгрузкой DLL с помощью FreeLibrary.

Например, DLL с расширениями оболочки загружается динамически, чтобы отменить регистрацию расширений вручную. В то же время вы запускаете поток в DllMain для инициализации ведения журнала. В этом случае вызывается DllUnregisterServer, который успешно выгружает DLL. Затем, как и следовало ожидать, система вызывает FreeLibrary.

В этом примере может случиться так, что поток, вызванный из DllMain, либо не завершил выполнение, либо еще не начался, а DLL уже выгружена из контекста процесса. В результате области памяти повреждаются и нарушения прав доступа могут возникнуть в любой момент при обращении к этим областям.

Как решить: Дождитесь окончания потока инициализации в экспортируемых функциях DLL.

Заключение

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

Apriorit имеет команду квалифицированных разработчиков систем Windows, которые могут помочь вам с проектом Windows любой сложности. Свяжитесь с нами, используя форму ниже!

Читайте также: