Shell extension что это
Работаем с жёсткими и символическими ссылками в Windows (часть 2)
— Это продолжение статьи. Начало читайте здесь.
Рассмотренный в прошлой заметке набор расширений для «Проводника» ограничен возможностями старых версий Windows и NTFS и позволяет создавать жёсткие ссылки на файлы и мягкие — на каталоги. В программе Link Shell Extension этой проблемы нет, но её установка и использование немного сложнее.
Как и в предыдущем случае, продукт поставляется бесплатно для всех актуальных версий Windows, но пользователю придётся самостоятельно инсталлировать необходимые библиотеки Microsoft Visual C++, скачав с сайта файл вида «vcredist_платформа.exe» и запустив его с правами администратора. Далее устанавливается сама программа для соответствующей платформы. Кроме того, рекомендуется использовать некий драйвер поддержки символических ссылок в Windows XP — он доступен для процессорных архитектур x86 и x64, устанавливается с помощью утилиты senable.exe с параметром install из командной строки (предварительно нужно распаковать архив) и позволяет делать символические ссылки не только на каталоги, но и на файлы.

При инсталляции Link Shell Extension можно выбрать русский язык, но контекстные меню «Проводника» локализованы не полностью, а утилита настройки и вовсе не переведена на русский язык. Использование расширения напоминает обычное копирование и вставку: из контекстного меню работы с файлом или каталогом нужно выбрать пункт «Запомнить источник», а затем «Поместить как». Здесь же можно отменить действие.
Расширение позволяет создавать ссылки перетаскиванием объекта с зажатой правой кнопкой мыши (когда пользователь её отпускает, появляется контекстное меню), а также добавляет новую закладку в окно просмотра свойств файла и выделяет ссылки специальным значком, добавляющимся к стандартной иконке.

К сожалению, в Windows нельзя создавать жёсткие ссылки на каталоги, но имеется похожий объект под названием Junction (связь). Он создается и используется почти аналогично и помечается специальным значком с несколькими звеньями цепи. Единственное важное отличие от хардлинка: если удалить исходную папку, то связь будет ссылаться на недоступное место. Источник связи, а также симлинка на каталог можно заменить перетаскиванием (с нажатой правой кнопкой мыши) или через контекстное меню, выбрав предварительно новый источник.

Но самые интересные возможности касаются копирования каталогов. Можно, к примеру, клонировать каталог таким образом, что подкаталоги копии останутся подкаталогами, а файлы будут заменены на мягкие или жёсткие ссылки. Решены здесь и проблемы копирования содержащих ссылки каталогов — пользователь может сохранять их логику различными способами. Есть в наборе расширений монтирование разделов в каталог (в качестве источника нужно выбрать раздел) и многое другое — полное описание не уместится в короткой заметке. Подробная информация обо всех функциях Link Shell Extensions доступна на сайте проекта.
Проект активно развивается, и в нём находят недочёты. Например, выскакивающий диалог контроля учётных записей пользователей при выполнении операций с символическими ссылками и связями в Windows 7 и Vista. Могут быть проблемы со съёмными носителями и бог знает что ещё. Важно понимать, что это программное обеспечение вы используете на свой страх и риск, и устанавливать его на рабочую машину неопытным пользователям категорически не рекомендуется.
Shell extension что это
Определения

Для реализации задуманного нам понадобятся интерфейсы IContextMenu и IShellFolder. Указатель на главный интерфейс IshellFolder, соответствующий «Рабочему столу» оболочки, можно получить, используя функцию SHGetDesktopFolder, объявление которой выглядит так:
Синтаксис первой и последней функции, я думаю, понятен и без разъяснений. Функция TrackPopupMenu, собственно, и выводит на экран контекстное меню. Параметры этой функции принимают значения:
function ParseDisplayName (hwndOwner: HWND;pbcReserved: Pointer; lpszDisplayName: POLESTR; out pchEaten: ULONG;out ppidl: PItemIDList; var dwAttributes: ULONG): HResult; stdcall;
После удачного завершения надо бы перейти к классу родителя нашего NotePad.exe. Воспользуемся для этого функцией IShellFolder.BindToObject, объявленной следующим образом:
И после очередной строчки кода:
мы получим в переменной ShellFolder0 указатель на интерфейс IShellFolder, соответствующий папке C:\Windows. Теперь мы можем узнать PItemIDList нашего NotePad:
Для чего все это было написано?
Теперь мы без зазрений совести можем приступать к выводу нашего контекстного меню:
Обработка результата команды TrackPopupMenu:
Недоработки…
…а где их нет? То есть, конечно, этот компонент работает, я его использую, но в нем (пока) отсутствуют некоторые полезные функции. К примеру, если вы заглянете в файл ShlObj.pas, то обнаружите, что там, помимо использованного нами интерфейса IcontextMenu, объявлены также интерфейсы IContextMenu2 и IContextMenu3, которые используются для расширения базовых функций интерфейса (к примеру, IContextMenu2 используется для работы с элементами подменю). Кроме того, небольшая доработка компонента даст возможность включать в него свои собственные пункты меню (сравните рис. 3 и рис. 4).
Разработка Shell Extensions для Windows Explorer
Для повышения удобства разрабатываемых продуктов, мы стараемся обеспечить максимальный уровень интеграции функционала в операционную систему, чтобы пользователю было удобно использовать весь потенциал приложения. В этой статье будут рассмотрены теоретические и практические аспекты разработки Shell Extensions, компонентов позволяющих интегрироваться в оболочку операционной системы Windows. В качестве примера рассмотрим расширение списка контекстного меню для файлов, а так же проведем обзор уже существующих решений в этой области.
Вообще говоря, существует огромное множество вариантов интеграционных компонентов оболочки операционной системы Windows, например: апплеты панели управления, хранители экрана и прочее, однако в данной статье мне бы хотелось подробнее остановиться на возможностях расширения Windows Explorer, компонента ОС, который мне приходилось расширять больше остальных, ввиду его функциональной нагрузки.
Добавим в Assembly.cs следующие директивы, позволяющие использовать нашу сборку как COM объект:
Нам понадобиться импортировать некоторые функции Windows API.
Функция DragQueryFile позволит нам получить список файлов выбранных в каталоге, SHChangeNotify оповестить операционную систему о том, что оболочка была изменена.
Так как мы разрабатываем COM объект, который расширяет контекстное меню, мы должны реализовать интерфейс IShellExtInit. В методе Initialize мы получим базовую информацию о каталоге, в котором выполняемся.
Также необходимо описать и реализовать COM интерфейс IContextMenu. Значение поля PreserveSig, равное true, инициирует непосредственное преобразование неуправляемых сигнатур со значениями HRESULT или retval, а значение false вызывает автоматическое преобразование значений HRESULT или retval в исключения. По умолчанию для поля PreserveSig используется значение true.
Метод QueryContextMenu будет вызван при вызове контекстного меню, в нем нам будет нужно реализовать функционал по добавлению пункта меню, GetCommandString будет возвращать некоторые детали по данной команде, ее описание и прочее. InvokeCommand будет вызван при выборе пункта меню, который мы добавим.
Для COM объекта так же необходимо реализовать функции установки и удаления.
В этой функции мы выполняем регистрацию нашего компонента в реестре, так как у нас компонент расширяющий функционал контекстного меню, мы регистрируемся в разделе ContextMenuHandlers (*\\shellex\\ContextMenuHandlers\\ExShell). После регистрации перезапускаем процесс explorer.exe для того, чтобы наши изменения сразу вступили в силу.
Функция удаления компонента, очищаем реестр от созданных ранее ключей.
Далее переходим к процессу реализации интерфейсных функций.Реализуем интерфейсы IShellExtInit, IContextMenu. Не буду детально описывать весь код этого класса, остановлюсь на реализации функций данных интерфейсов.
Функция инициализации компонента, запускается при открытии каталога или любого другого объекта, в контексте которого может находиться контекстное меню. Используем интерфейс IDataObject для получения данных о текущем объекте, в частности нас интересует hGlobal. Этот Handle идентифицирует текущий объект, внутри которого и происходит наше выполнение.
Далее рассмотрим функцию, которая вызывается при выпадении контекстного меню.
В этом участке кода проверяем, что выполняемся в нужном контексте и пытаемся запросить количество выбранных в каталоге файлов, а так же сохранить список этих файлов. Также замечу, что при передаче iFile = 0xffffffff в функцию DragQueryFile она вернет количество файлов в каталоге.
Здесь добавляем новый пункт меню при помощи вызова функции InsertMenuItem, затем подготавливаем и добавляем иконку к этому пункту меню, а так же разделительную линию для эстетической красоты. Структура MENUITEMINFO описывает наш пункт меню, а именно его тип (ftype), содержащиеся данные (dwTypeData), состояние (fState), идентификатор пункта меню (wID). Переменная hMenu идентифицирует текущее выпавшее меню, iMenu позиция по которой мы добавляемся. Для того, чтобы получить более полную информацию, можно обратиться в MSDN.
Далее рассмотрим функцию GetCommandString
Данная функция возвращает независимое от языка описание команды, а так же краткую подсказку в виде helptext соответственно.
Ну и последняя функция, которая будет вызвана при выборе нашего пункта меню:
Тут все достаточно прозрачно.
Вот так выглядит наш компонент в ShellExView:
Так он выглядит при раскрытом контекстном меню:
P.S Расширение не тестировал на Windows 8, судя по отзывам, для корректной работы в реестре нужно установить в разделе HKEY_CLASSES_ROOT\CLSID\
Пошаговое руководство по написанию расширения
Автор: Michael Dunn
Перевод: Инна Кирюшкина
Алексей Кирюшкин
Источник: The Code Project
Опубликовано: 17.04.2001
Исправлено: 24.02.2006
Версия текста: 1.3
Часть I является введением в расширения оболочки, а также содержит пример расширения контекстного меню.
Что представляют собой расширения оболочки?
Существует много типов расширений оболочки. Каждый тип загружается при наступлении конкретного события. Вот несколько наиболее общих типов и ситуаций, при которых они загружаются
| Типы | Когда загружаются | Что делают |
|---|---|---|
| Обработчик контекстного меню | Правый щелчок на файле или папке. В версиях оболочки 4.71+ также правый щелчок на фоне окна, отображающего каталог. | Добавляет пункты к контекстному меню. |
| Обработчик страниц свойств | При отображении свойств файлов | Добавляет страницы свойств |
| Обработчик перетаскивания | Пользователь перетаскивает файлы правой кнопкой мыши в окно каталога или на рабочий стол | Добавляет пункты к контекстному меню, появляющемуся при отпускании кнопки. |
| Обработчик сбрасывания | Пользователь перетаскивает и сбрасывает объекты на файл | Любое желаемое действие |
| Всплывающие описания | Указатель мыши находится над файлом или другим объектом | Возвращает строку, которая отображается во всплывающей подсказке. |
WinZip содержит код, который добавляет пункты в меню, обеспечивает подсказку (текст, который появляется в строке состояния проводника), и выполняет нужные действия, когда пользователь выбирает одну из команд WinZip. WinZip также содержит обработчик перетаскивания. Этот тип расширения очень похож на расширение контекстного меню, но он загружается, когда пользователь перетаскивает файл, используя правую кнопку мыши. Вот что этот обработчик добавляет к контекстному меню:
Существует много других типов и Microsoft продолжает добавлять их в каждой новой версии Windows. Сейчас мы рассмотрим расширения контекстного меню, поскольку они легко и просто пишутся и в результате красиво смотрятся (одно удовольствие!).
Прежде чем начать кодирование, несколько указаний, которые облегчат нам работу. После загрузки расширение остается на некоторе время в памяти, что делает невозможным повторную загрузку. Чтобы иметь возможность часто перегружать расширение в оболочке, создадим ключ в реестре:
и установим начальное значение = 1. В Windows 9x это самый лучший выход.
В Windows NT/2000 откроем раздел:
создадим параметр типа DWORD, назовем его DesktopProcess и установим значение = 1.
При этом рабочий стол и панель задач запустятся в одном процессе и последующие окна проводника запускаются каждое в своем собственном процессе. Это позволит вам делать отладку в одном окне проводника, и когда вы его закроете, ваша DLL автоматически выгрузится, и вы избегните проблем с использованным файлом. Вам необходимо сделать перерегистрацию в Windows, чтобы эти изменения вступили в силу.
Как делать отладку в 9x я объясню немного позже.
Давайте создадим и запустим расширение, которое просто выводит сообщение о том, что оно загружено и работает. Мы привяжем его к TXT-файлам, так что наше расширение будет вызываться, когда пользователь щелкнет правой кнопкой мыши на текстовом файле.
Использование AppWizard.
Я еще не рассказал вам, как использовать интерфейсы расширений оболочки? Не беспокойтесь, я объясню, когда дойду до этого. Это лучше усвоится, если будет сопровождаться примерами. Я объясню понятия и буду сопровождать их кодом примера. Можно было-бы объяснить все сначала, а затем дать код, но я нахожу, что это тяжелее для понимания.
В любом случае запускайте MS VC и мы начнем.
Интерфейс инициализации
Чтобы добавить IShellExtInit к нашему проекту, откройте SimpleShExt.h и введите выделенные строки:
В SimpleShlExt.cpp добавьте определение функции:
Заметим, что крайне важно избежать любых ошибок, особенно с указателями. поскольку наше расширение запускается в пространстве процесса проводника, и, если мы ошибемся, то разрушим проводник. В Win 9х такая ошибка приводит к необходимости перезагружать компьютер.
Теперь, когда мы имеем дескриптор HDROP, мы можем получить нужное имя файла:
Интерфейс взаимодействия с контекстным меню
А затем добавим прототипы методов IContextMenu:
Модификация контекстного меню
Я следовал объяснениям Dino в коде, написанном мною. Его метод получения возвращаемого значения эквивалентен методу on-line MSDN до тех пор, пока вы считаете количество пунктов вашего меню с помощью uidFirstCmd и прибавляете 1 для каждого добавленного пункта. Наше простое расширение будет иметь только один пункт, поэтому функция QueryContextMenu() совсем проста:
Отображение подсказки в строке состояния
Код нашей GetCommandString() выглядит так:
Здесь нет ничего фантастического. Я просто преобразовываю строку в подходящий набор символов. Если вы никогда не использовали ATL макросов конвертирования, вы определенно должны прочитать о них, т.к. они намного облегчают жизнь, когда необходимо передать строку UNICODE COM-методам и OLE-функциям. Я использую T2CW и T2CA в коде, приведенном выше, чтобы преобразовать строку в UNICODE и ANSI соответственно. Макрос USES_CONVERSION в начале функции объявляет локальную переменную, которая используется в конверсионных макросах.
Выполнение выбора пользователя
Регистрация расширения оболочки
Итак, мы осуществили все интерфейсы, но как сделать, чтобы проводник мог использовать наше расширение? ATL автоматически генерирует код, который регистрирует нашу DLL как COM сервер, но это всего лишь позволит другим приложениям использовать нашу DLL. Для того чтобы сообщить проводнику, что наше расширение существует, мы должны зарегистрировать его в секции, которая содержит информацию о TXT-файлах:
и установим его default значение согласно нашему GUID:»<5E2121EE-0300-11D4-8D3B-444553540000>«.
Вот как выглядят данные для регистрации:
ОК. Конец статьи. Последняя деталь о регистрации. В Windows NT/2000 мы также должны внести наше расширение в список «одобренных» расширений. Если мы этого не сделаем, наше расширение не будет доступно пользователю, который не имеет прав администратора. Этот список находится в
Отладка расширения оболочки
Как все это выглядит?
Так выглядит контекстное меню после добавления нашего пункта:
Так выглядит строка статуса с выведенной подсказкой:
А так выглядит сообщение, показывающее имя файла, который был отмечен:
Продолжение следует.
Во второй части будет рассмотрено новое расширение контекстного меню, которое покажет, как действовать в случае нескольких отмеченных файлов.
Link Shell Extension
Сегодня я расскажу о программе, что поможет жаждущим оптимизировать хранение данных на компьютере или в локальной сети.
Мне она пригодилась на работе, когда было решено навести порядок на сетевом диске, но требовалась совместимость с многочисленными старыми ярлыками. Для разрешения ситуации каталоги были переименованы, а для совместимости со старыми ярлыками, были созданы скрытые символические ссылки с именами старых каталогов.
Для начала немного теории:
Символическая ссылка — специальный файл в файловой системе, в котором вместо пользовательских данных содержится путь к файлу, открываемому при обращении к данной ссылке (файлу).
Жёсткая ссылка Жёсткая ссылка связывает индексный дескриптор файла с каталогом и дает ему имя. У файла может быть несколько жёстких ссылок: в таком случае он будет фигурировать на диске одновременно в различных каталогах или под различными именами в одном каталоге. При редактировании файла через одну из ссылок на него, содержимое по другим ссылкам тоже изменится
Точка соединения NTFS (Junction Point) — нововведение в файловой системе NTFS 3.0 (файловая система по умолчанию в Windows 2000). Суть нововведения заключается в том, что указанный логический диск либо папка будет отображаться как папка на другом логическом диске либо в другой папке. Эта возможность позволяет создавать некоторые эффекты с файловой системой (например, хранить два профиля одного и того же пользователя и переключаться между ними без особых проблем). Точка соединения реализована в NTFS как особый тип точки повторной обработки (англ. reparse point)
Целью ссылки может быть любой объект: например другая ссылка, файл, каталог или даже несуществующий файл (в последнем случае при попытке открыть его должно выдаваться сообщение об отсутствии файла).
Программа позволяет создавать жесткие ссылки, символические ссылки, Junction points, volume mount points. Она позволяет редактировать и копировать их.
Пользоваться утилитой просто. После установки в меню Проводника у вас появится новая команда «Запомнить источник ссылки». К примеру нам нужно создать создать жёсткую ссылку на файл. Щелкаем по нему правой кнопкой мыши и выбираем в меню опцию «Запомнить источник ссылки».
Перетаскивание файлов правой кнопкой мыши так-же дает свой результат: можно быстро создать жесткую или символическую ссылку.
В каталоге назначения, щелкнув по пустому месту правой кнопкой выбираем меню «Поместить как…». А там выбираем создать жесткую ссылку.
Если работа ведется не над файлом, а над каталогом, но выбор опций больше.
Выше я перечислил лишь малую часть возможностей программы.
По ссылке вы можете ознакомиться с иллюстрированной документацией о программе и скачать её.









