Winrar shell extension что это

Обновлено: 06.07.2024

Для повышения удобства разрабатываемых продуктов, мы стараемся обеспечить максимальный уровень интеграции функционала в операционную систему, чтобы пользователю было удобно использовать весь потенциал приложения. В этой статье будут рассмотрены теоретические и практические аспекты разработки 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\\InprocServer32 следующее значение ThreadingModel = Apartment.

Думаю, вы замечали, что некоторые программы добавляют собственные пункты в системное контекстное меню. Например, WinRAR добавляет "Сжать" и "Распаковать в…", ICQ - "Переслать пользователю" и пр. Механизм, с помощью которого ваш код "внедряется" в оболочку Windows, называется Shell Extensions - именно о нем пойдет речь…

Определения


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

Shell Extensions - набор сервисных функций Windows API, призванный обеспечить расширение базовых функций оболочки Windows Explorer за счет наших надстроек. В числе основных функций Shell Extensions:

  • работа с системными контекстными меню;
  • работа с папками и объектами из пространства имен оболочки Windows (Мои Документы, Принтеры, Панель управления…);
  • использование механизма Drag&Drop;
  • создание и использование ярлыков.

Для реализации задуманного нам понадобятся интерфейсы IContextMenu и IShellFolder. Указатель на главный интерфейс IshellFolder, соответствующий "Рабочему столу" оболочки, можно получить, используя функцию SHGetDesktopFolder, объявление которой выглядит так:


Эта функция возвращает нам указатель на интерфейс IShellFolder, который возвращается в переменной ppshf. Далее допустим, что у нас в компоненте имеется поле под названием ShellObject типа String, в котором хранится путь к необходимому объекту (к примеру - C:\Windows\NotePad.exe), и что нам нужно получить его контекстное меню (рис. 2). Для этого сначала используем метод из интерфейса IShellFolder:

  • hwndOwner - дескриптор родительского окна (0);
  • cidl - количество элементов, на которое указывает значение apidl (1);
  • apidl - параметр, представляющий собой уникальный идентификатор объекта;
  • riid - глобальный уникальный идентификатор системы Windows (IID_IContextMenu из файла ShlObj.pas);
  • prgfInOut - зарезервировано, должно быть nil;
  • ppvOut - переменная, которая получит указатель на "заказанный" интерфейс.

После использования этого оператора нам понадобится обратиться к функциям WinAPI - для работы с контекстными меню. Это, в первую очередь:

Синтаксис первой и последней функции, я думаю, понятен и без разъяснений. Функция TrackPopupMenu, собственно, и выводит на экран контекстное меню. Параметры этой функции принимают значения:

  • hMenu - дескриптор контекстного меню. Это тот самый Menu, который мы создали с помощью CreatePopupMenu;
  • uFlags - выравнивание относительно координат. Возможные значения: TPM_CENTERALIGN, TPM_LEFTALIGN, TPM_RIGHTALIGN, TPM_LEFTBUTTON, TPM_RIGHTBUTTON, TPM_RETURNCMD. Этот параметр используется для возврата команды (как будет показано ниже);
  • x, y - координаты, по которым будем "впрыгивать" наше меню;
  • nReserved - соответственно, приравниваем к нулю;
  • hWnd - дескриптор родительского окна;
  • prcRect - указатель на структуру TRect, которая задает "окно" в экранных координатах в пределах которого пользователь может щелкать без каких-либо исчезновений контекстного меню. Если = nil, то при нажатии мышкой за пределами контекстного меню оное исчезнет.

Возвращаемое значение показывает наличие команды или ее отсутствие. Если True - пользователь выбрал пункт; False - соответственно, не выбрал.

А теперь - самое главное

Ну что ж, сделали мы Menu - остается наполнить его содержимым, соответствующим нашему ShellObject. Для этого узнаем сначала его идентификатор (PItemIDList) - сделаем это при помощи метода ParseDisplayName из интерфейса IshellFolder. Этот метод объявлен следующим образом:

function ParseDisplayName (hwndOwner: HWND;pbcReserved: Pointer; lpszDisplayName: POLESTR; out pchEaten: ULONG;out ppidl: PItemIDList; var dwAttributes: ULONG): HResult; stdcall;

  • lpszDisplayName - имя объекта, для которого надо найти PItemIDList;
  • pchEaten - возвращает символы, которые были правильно разобраны;
  • ppidl - как раз то, что нам нужно (сохраняем в FItemIDList);
  • dwAttributes - атрибуты для только что найденного FItemIDList.

Но здесь следует проявлять осторожность. Как вы помните, нам нужно вывести контекстное меню для C:\Windows\NotePad.exe. Но сделать это прямо нельзя. Поэтому найдем сначала PItemIDList для папки C:\Windows - контейнера нашего NotePad.exe. Пишем:

  • ShellFolder - значение, которое мы получили из SHGetDesktopFolder;
  • FEaten,FAtt - как я уже говорил, мне они не пригодились - но, чем черт не шутит, лучше их все-таки придержать;
  • FItemIDList - сохраняем, он нам еще понадобится.

После удачного завершения надо бы перейти к классу родителя нашего NotePad.exe. Воспользуемся для этого функцией IShellFolder.BindToObject, объявленной следующим образом:

  • pidl - наш FItemIDList;
  • riid - в этом случае указывает на экземпляр IID_IshellFolder;
  • ppvOut - указывает, куда нам его запихнут (скажем, ShellFolder1).

И после очередной строчки кода:

мы получим в переменной ShellFolder0 указатель на интерфейс IShellFolder, соответствующий папке C:\Windows. Теперь мы можем узнать PItemIDList нашего NotePad:

Для чего все это было написано?

Теперь мы без зазрений совести можем приступать к выводу нашего контекстного меню:

Что тут написано. Во-первых - вызов интерфейса IcontextMenu, сопряженного с объектом FItemIDList папки ShellFolder0. Во-вторых, создание дескриптора пустого контекстного меню; заполнение контекстного QueryContextMenu; использование команды TrackPopupMenu для вывода контекстного меню в точку (100, 100).

Обработка результата команды TrackPopupMenu:

  • переменная Command типа LongBool преобразуется в тип Longint;
  • CommandStr - переменная, в которую заносится название команды;
  • DoCommandEvent - процедура обработки события;
  • структура ICI типа _CMINVOKECOMMANDINFO задает параметры, необходимые для запуска на исполнение кода, приписанного выбранному пункту меню по умолчанию;
  • InvokeCommand (ICI) - запуск кода по умолчанию.

Недоработки…

…а где их нет? То есть, конечно, этот компонент работает, я его использую, но в нем (пока) отсутствуют некоторые полезные функции. К примеру, если вы заглянете в файл ShlObj.pas, то обнаружите, что там, помимо использованного нами интерфейса IcontextMenu, объявлены также интерфейсы IContextMenu2 и IContextMenu3, которые используются для расширения базовых функций интерфейса (к примеру, IContextMenu2 используется для работы с элементами подменю). Кроме того, небольшая доработка компонента даст возможность включать в него свои собственные пункты меню (сравните рис. 3 и рис. 4).

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

Руководство полного идиота по написанию расширений оболочки - Часть I

Расширение оболочки (shell extension) - это COM объект, который добавляет некоторый вид функциональности к оболочке Windows - проводнику (Explorer). Все типы расширений присутствуют в оболочке, однако слишком мало сопровождающей информации о том, что они из себя представляют и как написать свои собственные расширения. Я рекомендую отличную книгу Dino Esposito "Visual C++ Windows Shell Programming", если вы хотите получить обзор многих аспектов оболочки Windows. Для тех, у кого нет книги или кого интересуют только конкретные расширения, я написал это руководство. Оно поразит вас или по крайней мере обеспечит хорошее понимание того, как писать собственные расширения. Это руководство предполагает, что вы знакомы с основами COM и ATL.

Часть I является введением в расширения оболочки, а также содержит пример расширения контекстного меню.

Что представляют собой расширения оболочки?

Это понятие включает в себя две части: оболочка и расширение. Оболочка (Shell) - это проводник Windows (Explorer), а расширение (extension) - код, который вы пишете, чтобы получить управление проводником в определенный момент (например, при щелчке правой кнопкой мышки на doc-файле). Таким образом, расширение оболочки - это COM объект, который добавляет некоторые особености к проводнику.

Расширение оболочки является внутризадачным (in-process) сервером, который реализует несколько интерфейсов, обрабатывающих связи с проводником. ATL - легчайший путь быстро создать расширение и запустить его, без нее вам пришлось бы много раз вставлять код QueryInterface() и AddRef() . С помощью ATL намного легче отлаживать код расширения в Windows NT и 2000. Как именно это делается, я объясню позже.

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

Типы Когда загружаются Что делают
Обработчик контекстного меню Правый щелчок на файле или папке. В версиях оболочки 4.71+ также правый щелчок на фоне окна, отображающего каталог. Добавляет пункты к контекстному меню.
Обработчик страниц свойств При отображении свойств файлов Добавляет страницы свойств
Обработчик перетаскивания Пользователь перетаскивает файлы правой кнопкой мыши в окно каталога или на рабочий стол Добавляет пункты к контекстному меню, появляющемуся при отпускании кнопки.
Обработчик сбрасывания Пользователь перетаскивает и сбрасывает объекты на файл Любое желаемое действие
Всплывающие описания Указатель мыши находится над файлом или другим объектом Возвращает строку, которая отображается во всплывающей подсказке.

Теперь вам наверно интересно, как выглядят расширения в проводнике. Если у вас есть инсталлированный WinZip (а у кого его нет?), вы можете увидеть много типов расширений. Одно из них - обработчик контекстного меню. Вот что WinZip 8 добавляет к контекстному меню для сжатых файлов:



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



Существует много других типов и Microsoft продолжает добавлять их в каждой новой версии Windows. Сейчас мы рассмотрим расширения контекстного меню, поскольку они легко и просто пишутся и в результате красиво смотрятся (одно удовольствие!).

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

и установим начальное значение = 1. В Windows 9x это самый лучший выход.

В Windows NT/2000 откроем раздел:

создадим параметр типа DWORD, назовем его DesktopProcess и установим значение = 1.

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

Как делать отладку в 9x я объясню немного позже.

Что должно делать расширение контекстного меню ?

Использование AppWizard.

Я еще не рассказал вам, как использовать интерфейсы расширений оболочки? Не беспокойтесь, я объясню, когда дойду до этого. Это лучше усвоится, если будет сопровождаться примерами. Я объясню понятия и буду сопровождать их кодом примера. Можно было-бы объяснить все сначала, а затем дать код, но я нахожу, что это тяжелее для понимания.

В любом случае запускайте MS VC и мы начнем.

Запустите AppWizard и создайте новый ATL COM проект. Назовем его SimpleExt . Сохраните все установки по-умолчанию и нажмите "Finish". Теперь у нас есть пустой ATL- проект, из которого будет создана DLL, но нам необходимо добавить в него наш COM объект - расширение оболочки.

В дереве ClassView щелкните правой кнопкой на пункте SimpleExt Classes и выберите "New ATL Object". В "ATL Object" - мастере на первой странице уже отмечено "Simple Object", поэтому просто идите дальше. На второй панели введите SimpleShlExt в поле Short Name и щелкните OK. (Други редактируемые поля на панели будут заполнены автоматически). Созданный класс CSimpleShlExt содержит основной код COM - объекта. Мы добавим наш код к этому классу.

Интерфейс инициализации

Когда наше расширение загружается, проводник вызывает функцию QueryInterface() , чтобы получить указатель на интерфейс IShellExtInit . Этот интерфейс имеет только один метод, Initialize() :

Проводник использует этот метод, чтобы давать нам различную информацию. pidlFolder - это PIDL ( p ointer to an ID l ist) папки, содержащей активизированные файлы. (PIDL - это структура данных, которая однозначно идентифицирует любой объект в оболочке, независимо от того, объект это файловой системы или нет). pDataOdj - указатель на интерфейс IDataObject , с помощью которого мы извлекаем имена активизированных файлов. hProgID открывает HKEY, который мы используем, чтобы получить доступ к ключу реестра, содержащему регистрационные данные нашей DLL. Для нашего расширения необходимо использовать параметр pDataObj .

Чтобы добавить IShellExtInit к нашему проекту, откройте SimpleShExt.h и введите выделенные строки:

COM_MAP- это то, как ATL осуществляет QueryInterface() .

Затем в декларации класса добавьте прототип Initialize() . Нам также необходим буфер, чтобы сохранить имя файла:

В SimpleShlExt.cpp добавьте определение функции:

Имя файла сохранено в том же самом формате, в каком оно использовалось, когда вы переносили файл, используя стиль WS_EX_ACCEPTFILES . Это означает, что мы можем получить имена файлов используя то же API - DragQueryFile() . Начнем писать функцию, получающую доступ к данным, содержащимся в IDataObject :

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

Теперь, когда мы имеем дескриптор HDROP, мы можем получить нужное имя файла:

Если мы возвратим E_INVALIDARG , проводник не вызовет наше расширение повторно при правом щелчке мыши. Если мы возвратим S_OK, проводник вызовет QueryInterface() еще раз и получит указатель на другой интерфейс, который мы добавим - IContextMenu.

Интерфейс взаимодействия с контекстным меню

Как только проводник инициализировал наше расширение, он вызовет методы IContextMenu , позволяющие добавить пункты в меню, обеспечивающие подсказку в строке состояния и выполняющие выбор пользователя.

Добавление IContextMenu к нашему расширению подобно добавлению IShellExtInit . Откроем SimpleShlExt.h и добавим выделенные строки:

А затем добавим прототипы методов IContextMenu:

Модификация контекстного меню

IContextMenu имеет 3 метода. Первый из них, QueryContextMenu() , позволяет модифицировать меню. Вот его прототип:

hmenu это дескриптор контекстного меню. uMenuIndex - позиция, с которой мы должны начать добавлять свои пункты. uidFirstCmd и uidLastCmd - интервал идентификаторов команд, которые мы можем использовать для наших пунктов меню. uFlags указывает, почему проводник вызывает QueryContextMenu() , но об этом позже.

Описания возвращаемого значения различны в различных источниках. В книге Dino Esposito говорится, что это число пунктов меню, добавленных QueryContextMenu() . Библиотека MSDN, поступающая с VC6, говорит, что это ID последнего пункта меню, который мы добавим, плюс 1. Поздние on-line документы MSDN говорят:

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

Я следовал объяснениям Dino в коде, написанном мною. Его метод получения возвращаемого значения эквивалентен методу on-line MSDN до тех пор, пока вы считаете количество пунктов вашего меню с помощью uidFirstCmd и прибавляете 1 для каждого добавленного пункта. Наше простое расширение будет иметь только один пункт, поэтому функция QueryContextMenu() совсем проста:

Первое, что мы делаем - это проверяем uFlags . Вы можете найти полный список флагов в MSDN, но для контекстного меню важно только одно значение - CMF_DEFAULTONLY . Этот флаг сообщает расширениям, что добавляются только пункты меню по-умолчанию. Расширение ничего не должно добавлять, если этот флаг присутствует. Вот почему мы немедленно возвращаем 0, если выставлен это флаг. Если этого флага нет, мы модифицируем меню (используя hmenu ), и возвращаем 1, чтобы сообщить оболочке, что мы добавили 1 пункт меню.

Отображение подсказки в строке состояния

Следующий метод IContextMenu , который может быть вызван, это GetCommandString() . Если пользователь щелкает правой кнопкой на текстовом файле в окне проводника (в правом окне, если режим двухоконный), или укажет текстовый файл, а затем щелкнет на пункте меню File, то в строке состояния появится подсказка. Наша GetCommandString() возвратит строку, отображаемую в подсказке.

где idCmd - начинающийся с 0 счетчик, который указывает, какой пункт меню отмечен. Поскольку у нас только один пункт меню, idCmd всегда будет =0. Но если у нас есть изначально, скажем, 3 пункта меню, то idCmd может быть равен 0, 1 или 2. uFlags - другая группа флагов, которую я опишу позже. pwReserved можно проигнорировать. pszName - указатель на собственный буфер оболочки, где мы сохраним строку подсказки, которая будет высвечиваться. cchMax - это размер буфера. Возвращаемое функцией значение - одна из обычных констант HRESULT - S_OK или E_FAIL.

GetCommandString() также может быть вызвана, чтобы получить "действие" ("verb") от пункта меню. "Действие" - независимая от языка строка, которая идентифицирует операцию, производимую с файлом. Документы по ShellExecute() расскажут об объекте "действие" больше и это тема для другой статьи, но сокращенная версия такова: "действия" могут быть внесены в список в реестре ("open", "print") или могут быть созданы расширением динамически . Это позволяет вызывать расширение при выполнении ShellExecute() .

Во всяком случае, причина по которой я обо всем этом упомянул состоит в том, что нам нужно определить, для чего вызывается GetCommandString() . Если проводник требует строку подсказки, мы дадим ее. Если проводник потребует "действие" мы проигнорируем его запрос. Это как раз тот момент, когда параметр uFlags становится значимым. Если в параметре uFlags установлен бит GCS_HELPTEXT то проводник запрашивает подсказку. Если установлен бит GCS_UNICODE , мы должны возвратить строку в UNICODE.

Код нашей GetCommandString() выглядит так:

Здесь нет ничего фантастического. Я просто преобразовываю строку в подходящий набор символов. Если вы никогда не использовали ATL макросов конвертирования, вы определенно должны прочитать о них, т.к. они намного облегчают жизнь, когда необходимо передать строку UNICODE COM-методам и OLE-функциям. Я использую T2CW и T2CA в коде, приведенном выше, чтобы преобразовать строку в UNICODE и ANSI соответственно. Макрос USES_CONVERSION в начале функции объявляет локальную переменную, которая используется в конверсионных макросах.

Заметим одну важную вещь: lstrcpyn() гарантирует, что строка назначения будет завершена нулем. В этом ее отличие от CRT-функции strncpy() , которая не добавляет завершающий 0, если длина исходной строки больше или равна cchMax . Я предлагаю всегда использовать lstrcpyn() , и вам не нужно будет проверять конец строки после каждого вызова strncpy() , чтобы убедиться, что она закрыта нулем.

Выполнение выбора пользователя

Последний метод в IContextMenu - это InvokeCommand() . Это метод вызывается, когда пользователь щелкнет на пункте меню, который мы добавили. Прототип для InvokeCommand() :

Структура CMINVOKECOMMANDINFO содержит целую тонну информации. Но для наших целях важно позаботиться только о lpVerb и hwnd . lpVerb имеет двойное назначение - это может быть имя "действия" (см.выше), или индекс, сообщающий нам, какой из пунктов нашего меню был отмечен щелчком. hwnd - дескриптор окна проводника, в котором пользователь вызвал наше расширение.

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

Под этим ключом укажем ключ ShellEx , содержащий список расширений оболочки, вызываемых для TXT-файлов. Под ключом ShellEx ключ ContextMenuHandlers содержит список расширений контекстного меню. Каждое расширение создает свой субключ под ключом ContextMenuHandlers и устанавливает значение этого ключа по своему GUID. Например, для нашего простого расширения, создадим ключ:

и установим его default значение согласно нашему GUID:"".

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

Вот как выглядят данные для регистрации:

Каждая строка является именем ключа реестра. HKCR - сокращение для HKEY_CLASSES_ROOT . Ключевое слово NoRemove означает, что ключ не должен быть удален, когда сервер разрегистрируется. Последняя строка немного более сложная. Ключевое слово ForceRemove означает, что если ключ существует, он будет удален прежде, чем новый ключ записан. Рассмотрим остальную часть строки. Символ s означает, что подстрока, указанная после него будет сохранена, как значение по умолчанию для ключа SimpleShlExt.

Рассмотрим подробнее этот момент. Ключ, под которым мы зарегистрировали наше расширение - это HKCR\txtfile . Однако имя "txtfile" не является постоянным или предрешенным. Если вы посмотрите в HKCR\.txt , где было сохранено имя, то убедитесь, что это значение этого ключа по умолчанию. Это имеет два побочных эффекта:

  • Мы не можем надежно использовать RGS скрипт, т.к. "txtfile" может не быть корректным именем ключа.
  • Может быть установлен другой текстовый редактор, который будет ассоциировать TXT файлы с собой. Если он изменит значение по умолчанию ключа HKCR\.txt , все существующие расширения прекратят свою работу.

ОК. Конец статьи. Последняя деталь о регистрации. В Windows NT/2000 мы также должны внести наше расширение в список "одобренных" расширений. Если мы этого не сделаем, наше расширение не будет доступно пользователю, который не имеет прав администратора. Этот список находится в

В этом ключе мы создаем string переменную, чье имя - это наш GUID. Содержание строки может быть любым. Код, выполняющий это действие, входит в наши функции DllRegisterServer() и DllUnregisterServer() . Я не буду приводить его здесь, т.к. он слишком прост, но вы должны найти его в демонстрационном проекте.

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

В конечном счете вы напишете расширение, которое может быть далеко не простым, и вам придется его отлаживать. Откройте установки вашего проекта и на закладке Debug укажите полный путь к проводнику в окне "Remote executable path and file name" , например "C:\windows\explorer.exe". Если вы используете Windows 2000 и установили DesktopProcess как указывалось выше, нажмите F5 , откроется окно проводника и вы сможете начать отладку. Пока вы будете делать свою работу, вы не будете испытывать проблем с пересозданием DLL, т.к. когда вы закроете это окно, ваше расширение будет выгружено.

В Windows 9x вы должны отключить оболочку перед запуском отладчика. Щелкните Start и затем ShutDown . Держите нажатыми Ctrl+Alt+Shift и щелкните Cancel . Это отключит проводник и вы увидите, что панель задач исчезла. Вы можете вернуться в VC и нажать F5 , чтобы начать отладку.

Для остановки сеанса отладки нажмите Shift+F5 , чтобы закрыть проводник. Когда отладка будет завершена, вы можете запустить проводник с коммандной строки и нормально загрузить оболочку.

Как все это выглядит?

Так выглядит контекстное меню после добавления нашего пункта:



Наш пункт здесь!

Так выглядит строка статуса с выведенной подсказкой:





Продолжение следует.

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

Файл RarExt32.dll считается разновидностью файла WinRAR shell extension. Наиболее часто он используется в ПО WinRAR, разработанном компанией Eugene Roshal. Он использует расширение DLL и считается файлом Win32 DLL (Исполняемое приложение).

Первый выпуск файла RarExt32.dll в ОС Windows 10 состоялся 04/29/2019 в составе WinRAR 5.71. По нашим данным, это самая последняя дата выпуска от компании Eugene Roshal.

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




Совместимость с Windows 10, 8, 7, Vista, XP и 2000

Средняя оценка пользователей

Сведения о разработчике и ПО
Разработчик ПО: Alexander Roshal
Программа: WinRAR
Авторское право: Copyright © Alexander Roshal 1993-2019
Сведения о файле
Набор символов: Windows, Latin1
Код языка: English (U.S.)
Флаги файлов: (none)
Маска флагов файлов: 0x0000
Точка входа: 0x2ebad
Размер кода: 280064
Информация о файле Описание
Размер файла: 452 kB
Дата и время изменения файла: 2019:10:05 14:11:12+00:00
Тип файла: Win32 DLL
Тип MIME: application/octet-stream
Тип компьютера: Intel 386 or later, and compatibles
Метка времени: 2019:04:27 20:02:57+00:00
Тип PE: PE32
Версия компоновщика: 14.0
Размер кода: 280064
Размер инициализированных данных: 273920
Размер неинициализированных данных: 0
Точка входа: 0x2ebad
Версия ОС: 5.1
Версия образа: 0.0
Версия подсистемы: 5.1
Подсистема: Windows GUI
Номер версии файла: 5.71.0.0
Номер версии продукта: 5.71.0.0
Маска флагов файлов: 0x0000
Флаги файлов: (none)
Файловая ОС: Win32
Тип объектного файла: Executable application
Подтип файла: 0
Код языка: English (U.S.)
Набор символов: Windows, Latin1
Наименование компании: Alexander Roshal
Описание файла: WinRAR shell extension
Версия файла: 5.71.0
Внутреннее имя: WinRAR shell extension
Авторское право: Copyright © Alexander Roshal 1993-2019
Название продукта: WinRAR
Версия продукта: 5.71.0

✻ Фрагменты данных файлов предоставлены участником Exiftool (Phil Harvey) и распространяются под лицензией Perl Artistic.

Ошибки библиотеки динамической компоновки RarExt32.dll

Файл RarExt32.dll считается разновидностью DLL-файла. DLL-файлы, такие как RarExt32.dll, по сути являются справочником, хранящим информацию и инструкции для исполняемых файлов (EXE-файлов), например MpSigStub.exe. Данные файлы были созданы для того, чтобы различные программы (например, WinRAR) имели общий доступ к файлу RarExt32.dll для более эффективного распределения памяти, что в свою очередь способствует повышению быстродействия компьютера.

  • Нарушение прав доступа по адресу — RarExt32.dll.
  • Не удается найти RarExt32.dll.
  • Не удается найти C:\Program Files\WinRAR\RarExt32.dll.
  • Не удается зарегистрировать RarExt32.dll.
  • Не удается запустить WinRAR. Отсутствует требуемый компонент: RarExt32.dll. Повторите установку WinRAR.
  • Не удалось загрузить RarExt32.dll.
  • Не удалось запустить приложение, потому что не найден RarExt32.dll.
  • Файл RarExt32.dll отсутствует или поврежден.
  • Не удалось запустить это приложение, потому что не найден RarExt32.dll. Попробуйте переустановить программу, чтобы устранить эту проблему.

Файл RarExt32.dll может отсутствовать из-за случайного удаления, быть удаленным другой программой как общий файл (общий с WinRAR) или быть удаленным в результате заражения вредоносным программным обеспечением. Кроме того, повреждение файла RarExt32.dll может быть вызвано отключением питания при загрузке WinRAR, сбоем системы при загрузке RarExt32.dll, наличием плохих секторов на запоминающем устройстве (обычно это основной жесткий диск) или, как нередко бывает, заражением вредоносным программным обеспечением. Таким образом, крайне важно, чтобы антивирус постоянно поддерживался в актуальном состоянии и регулярно проводил сканирование системы.


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

Чтобы начать восстановление системы (Windows XP, Vista, 7, 8 и 10):

Если на этапе 1 не удается устранить ошибку RarExt32.dll, перейдите к шагу 2 ниже.


Шаг 2. Если вы недавно установили приложение WinRAR (или схожее программное обеспечение), удалите его, затем попробуйте переустановить WinRAR.

Чтобы удалить программное обеспечение WinRAR, выполните следующие инструкции (Windows XP, Vista, 7, 8 и 10):

После полного удаления приложения следует перезагрузить ПК и заново установить WinRAR.

Если на этапе 2 также не удается устранить ошибку RarExt32.dll, перейдите к шагу 3 ниже.


Шаг 3. Выполните обновление Windows.


Если ни один из предыдущих трех шагов по устранению неполадок не разрешил проблему, можно попробовать более агрессивный подход (примечание: не рекомендуется пользователям ПК начального уровня), загрузив и заменив соответствующую версию файла RarExt32.dll. Мы храним полную базу данных файлов RarExt32.dll со 100%-ной гарантией отсутствия вредоносного программного обеспечения для любой применимой версии WinRAR . Чтобы загрузить и правильно заменить файл, выполните следующие действия:

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

СОВЕТ ОТ СПЕЦИАЛИСТА: Мы должны подчеркнуть, что переустановка Windows является достаточно длительной и сложной задачей для решения проблем, связанных с RarExt32.dll. Во избежание потери данных следует убедиться, что перед началом процесса вы создали резервные копии всех важных документов, изображений, установщиков программного обеспечения и других персональных данных. Если вы в настоящее время не создаете резервных копий своих данных, вам необходимо сделать это немедленно.

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