Интеграция с оболочкой Windows ── контекстное меню, сопоставление файлов и изменения в Windows 11

· Обновлено: · · Windows, Расширения оболочки, Контекстное меню, Сопоставление файлов, COM, Windows 11, Проводник, MSIX, Разработка для Windows

История изменений (1 обновлений, последнее 31 Aug 2026)

Журнал изменений этой статьи. Там, где версия до правки была заархивирована, она остаётся доступной для чтения по постоянной ссылке с DOI.

Русский текст переписан по текущему навыку технического перевода как полный перевод японского оригинала.
Первая публикация
Цитирование статьи(DOI (зарегистрированный архив): 10.5281/zenodo.22176272)

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

Го Комура (2026). Интеграция с оболочкой Windows ── контекстное меню, сопоставление файлов и изменения в Windows 11. KomuraSoft LLC. https://comcomponent.com/ru/blog/windows-shell-integration-context-menu-file-association/

DOI (зарегистрированный архив)
10.5281/zenodo.22176272
DOI (последняя зарегистрированная версия)
10.5281/zenodo.22176273

Мне написали: «Перешли на ПК с Windows 11 — и контекстное меню приложения, которое вы нам когда-то делали, пропало». Если разобраться, оно не пропало. Щёлкните файл правой кнопкой и внизу меню выберите «Показать дополнительные параметры» — знакомое меню появится как раньше. Пункты вашего приложения просто спрятали на один щелчок глубже. С мест говорят: «лишний щелчок» и «стало больше обращений, что пункт не находят».

Это не сбой и не ошибка настройки, а изменение в Windows 11. Контекстное меню Проводника стало двухуровневым: новое и старое. Условия, при которых пункт попадает в новое меню, совсем другие, чем раньше.

При этом основа — сопоставление файлов и расширения оболочки — по-прежнему старый мир COM и реестра. Ключ расширения указывает на ProgID, verb у ProgID хранит командную строку, а более сложное расширение работает как внутрипроцессный COM-сервер (DLL), загружаемый в Проводник. Эта схема не менялась больше двадцати лет. Без знания и неизменной основы, и меню, которое Windows 11 разделила на два уровня, не отличить «меню нет», «оно спрятано» и «оно показывается дважды».

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

1. Сначала выводы

  • Основа контекстного меню и сопоставления файлов — трёхступенчатая схема реестра «ключ расширения → ProgID → verb». Ключ расширения — указатель на ProgID, ProgID — сущность, а shell\<verb>\command под ним хранит командную строку.1
  • HKEY_CLASSES_ROOT (HKCR) — не отдельный куст, а объединённое представление HKLM\Software\Classes и HKCU\Software\Classes. Регистрацию для всех пользователей пишите в HKLM, для одного пользователя — в HKCU, а HKCR считайте только для чтения.2
  • Приложение по умолчанию (то, что открывается двойным щелчком) выбирает пользователь; программа забрать его не может. ОС защищает выбор пользователя; установщик может зарегистрироваться как кандидат.3
  • Классическое расширение оболочки — внутрипроцессная COM DLL, загружаемая в Проводник. Сбой или задержка расширения бьют по Проводнику целиком (и по другим приложениям, которые пользуются оболочкой); в 64-разрядной среде нужна 64-разрядная DLL; реализация на управляемом коде не поддерживается.45
  • В Windows 11 контекстное меню разделено на два уровня. В новое меню попадают только команды, зарегистрированные через IExplorerCommand плюс удостоверение пакета; классические расширения IContextMenu отодвинуты в старое меню под «Показать дополнительные параметры» (Shift+F10).67
  • Официальный путь поместить свою команду в новое меню — зарегистрировать нативную DLL, реализующую IExplorerCommand, в манифесте MSIX (desktop4:FileExplorerContextMenus). Приложение, которое нельзя упаковать в MSIX, может получить только удостоверение через sparse package (MSIX с внешним расположением).78
  • Если нужно только «открыть этим приложением», по-прежнему хватает сопоставления и статического verb. DLL расширения оболочки не нужна, и сама Microsoft прямо говорит: «выберите самый простой метод, который закрывает требования (статический verb)».9
  • После регистрации или изменения уведомите через SHChangeNotify(SHCNE_ASSOCCHANGED); при удалении удалите ProgID, но не удаляйте значение по умолчанию ключа расширения — так сказано в официальном руководстве. В интеграцию с оболочкой входит и то, как вы чистите регистрацию.110

Одной фразой: мир сопоставлений и verb не изменился; изменился только показ меню — в Windows 11 он стал двухуровневым. Дальше идём от основы.

На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 16, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle

2. Как устроено сопоставление файлов ── трёхступенчатая схема ключ расширения → ProgID → verb

2.1. Читаем трёхступенчатую схему на одном примере

Что происходит при двойном щелчке по файлу данного расширения, решают три уровня ключей реестра.1

HKEY_CLASSES_ROOT
   .kmrpt                                  ← (1) Ключ расширения
      (Default) = KomuraSoft.Report.1      ←     Указатель, который только именует ProgID
      OpenWithProgids
         KomuraSoft.Report.1               ←     Кандидат в «Открыть с помощью»
   KomuraSoft.Report.1                     ← (2) ProgID (сущность сопоставления)
      (Default) = Документ Komura Report
      DefaultIcon
         (Default) = "C:\Program Files\KomuraSoft\Report.exe",0
      shell                                ← (3) Список verb (глаголов)
         open
            command
               (Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
  • (1) Ключ расширения (.kmrpt) только указывает на имя ProgID как значение по умолчанию. Писать команду прямо сюда — ошибка.
  • (2) ProgID (KomuraSoft.Report.1) — сущность сопоставления; в нём отображаемое имя, значок и список verb.
  • (3) Verb — действие вроде «открыть» или «печать», а значение по умолчанию shell\open\command — реально запускаемая командная строка.

Благодаря этому разделению несколько расширений (например .kmrpt и .kmrpt-file) можно направить на один ProgID, а при обновлении приложения — подменить ProgID.

Трёхступенчатая схема сопоставления файловКлюч расширения — указатель, чьё значение по умолчанию именует ProgID; ProgID — сущность с отображаемым именем, значком и списком verb; значение по умолчанию command под verb — реально запускаемая командная строказначение по умолчанию указывает на ProgIDКлюч расширения .kmrptProgID KomuraSoft.Report.1verb (open и другие под shell)значение по умолчанию commandЗапускается Report.exeТакже хранит отображаемое имя и DefaultIcon

Рис. 1: Ключ расширения — указатель, ProgID — сущность, а command у verb — реально запускаемая командная строка.

2.2. HKCR — «объединённое представление»: куда пишете, меняет смысл

Пример выше показан под HKEY_CLASSES_ROOT (HKCR), но HKCR — не физическое место хранения, а объединённое представление HKLM\Software\Classes и HKCU\Software\Classes. Если один и тот же ключ есть в обоих, побеждает сторона HKCU.2

HKCR — объединённое представлениеHKCR — это Classes из HKLM и HKCU, наложенные друг на друга; если один и тот же ключ есть в обоих, побеждает HKCU; регистрацию пишите явно в HKLM или HKCU и считайте HKCR только для чтенияHKLM\Software\Classes (все пользователи)HKCR (объединённое представление)HKCU\Software\Classes (на пользователя)Если ключ один и тот же, побеждает HKCUСчитайте только для чтения (для проверки)

Рис. 2: HKCR — вид Classes из HKLM и HKCU, наложенных вместе; место записи всегда указывайте явно — одну из двух сторон.

Куда писать Что это значит Какие права нужны
HKLM\Software\Classes Регистрация общая для всех пользователей Права администратора
HKCU\Software\Classes Регистрация только для этого пользователя Не нужны
Писать прямо в HKCR Распределяется в зависимости от того, где уже лежит существующий ключ Зависит от случая

На практике безопасное правило — всегда писать регистрацию явно в HKLM или HKCU и считать HKCR только для чтения (для проверки). Стоит разобрать и связь с перенаправлением реестра WOW64. Данные сопоставления прямо под HKLM\Software\Classes вроде ключей расширения и ProgID общие между 32- и 64-разрядными представлениями реестра начиная с Windows 7, поэтому 32-разрядный установщик, который их пишет, не уходит на сторону Wow6432Node. Некоторые подразделы COM-регистрации вроде Classes\CLSID, напротив, перенаправляются, и при регистрации расширения оболочки (внутрипроцессный COM) важно, куда именно пишете — в 32- или 64-разрядное представление. Подробности — в «Ловушки перенаправления реестра 32/64 бит и виртуализации — Wow6432Node и «значения, которое записали, нет»».

2.3. Регистрация на стороне приложения ── App Paths, Applications, RegisteredApplications

Есть и три вида регистрации на стороне приложения, в паре со стороной файла (расширение и ProgID).11

  • App Paths (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths): регистрация, которая позволяет ShellExecuteEx запускать программу только по имени исполняемого файла. Microsoft рекомендует этот путь, потому что не нужно засорять переменную среды PATH.
  • Applications (HKCR\Applications\<приложение.exe>): задаёт способ открытия по умолчанию, когда произвольный файл передают через «Открыть с помощью», и отображаемое имя приложения (FriendlyAppName).
  • RegisteredApplications + Capabilities: объявляет расширения и типы MIME, которые приложение умеет обрабатывать, — это регистрация, из-за которой оно появляется кандидатом на странице Параметры приложений по умолчанию Windows.

Большинство обращений «наше приложение не появляется в списке приложений по умолчанию» — случаи, когда ProgID зарегистрировали, а эту регистрацию Capabilities пропустили.

Три вида регистрации на стороне приложенияРегистрация на стороне приложения бывает трёх видов — App Paths, Applications и RegisteredApplications — отвечающих соответственно за запуск только по имени файла, способ открытия по умолчанию в «Открыть с помощью» и появление на странице приложений по умолчаниюРегистрация на стороне приложенияApp PathsApplicationsRegisteredApplicationsЗапуск только по имени файлаПо умолчанию в Открыть с помощьюПоявляется на странице приложений по умолчаниюНужно объявление Capabilities

Рис. 3: Регистрация на стороне приложения бывает трёх видов, и чтобы появиться кандидатом приложений по умолчанию, нужна регистрация Capabilities.

2.4. Приложение по умолчанию принадлежит пользователю ── защита UserChoice

Запись ProgID как значения по умолчанию ключа расширения сама по себе не делает его приложением по умолчанию. Результат явного выбора пользователя в «Открыть с помощью» и подобном хранится в HKCU\...\Explorer\FileExts\<расширение>\UserChoice, и при разрешении сопоставления предпочитается эта сторона.

И важный момент: Windows не поддерживает программную смену приложения по умолчанию. Настройки приложения по умолчанию рассчитаны на пользователя через системный интерфейс Параметры; данные UserChoice обфусцированы, а драйвер-фильтр (UCPD.sys) блокирует запись из приложений. В управляемой среде официальное средство — групповая политика / политика MDM.3

То, что использовали инструменты вроде SetUserFTA, которые «имитируют хеш и переписывают», — обратная сторона этой защиты. В установщик своего приложения нужно класть не захват значения по умолчанию, а три вещи: (a) правильная регистрация ProgID и verb, (b) добавление себя в OpenWithProgIds и (c) при необходимости направление на страницу Параметры.

Разрешение приложения по умолчанию и защита UserChoiceРезультат явного выбора пользователя хранится в UserChoice и предпочитается при разрешении сопоставления; UCPD.sys блокирует перезапись из приложений, поэтому установщик может зарегистрироваться как кандидат и направить на страницу ПараметрыпредпочитаетсяUCPD.sys блокируетUserChoice (выбор пользователя)Разрешение сопоставленияЗначение по умолчанию ключа расширенияПерезапись из приложенияРабота установщикаЗарегистрировать ProgID и verbДобавить в OpenWithProgIdsНаправить на страницу Параметры

Рис. 4: При разрешении сопоставления предпочтение у выбора пользователя (UserChoice), и ОС защищает его от перезаписи приложениями.

3. Verb кроме «Открыть» ── print, edit, runas, свои verb

Verb — не только open. Среди стандартных verb, смысл которых знает ОС, рядом с open есть edit, print, play и preview; стандартный verb автоматически получает отображаемое имя по языку ОС. Verb по умолчанию при двойном щелчке определяется в порядке: значение по умолчанию ключа shell → первый verb в реестре → open → openwith.12

Порядок, в котором определяется verb по умолчаниюVerb по умолчанию при двойном щелчке — первый найденный в порядке значение по умолчанию ключа shell, первый verb в реестре, open, openwithесли нетесли нетесли нетзначение по умолчанию ключа shellПервый verb в реестреopenopenwith

Рис. 5: Verb по умолчанию при двойном щелчке — первый найденный в этом порядке.

Когда хотите добавить своё действие, зарегистрируйте свой verb.

KomuraSoft.Report.1
   shell
      open
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
      print
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" /print "%1"
      verify                          ← свой verb
         (Default) = Проверить отчёт (&V)   ← отображаемое имя в меню
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" /verify "%1"

Три мелких факта, которые полезно знать.

  • Зарегистрируйте verb с именем runas — и определите запуск с повышением прав, эквивалентный «Запуск от имени администратора»; его же используют API семейства ShellExecute, когда указывают runas.
  • Положите на ключ verb пустое значение с именем Extended — и он станет расширенным verb, который показывается только при Shift+правый щелчок. Удобно прятать опасную редко используемую операцию.12
  • У части сопоставлений старых приложений ещё есть конфигурация, которая отправляет документ в уже запущенный процесс через DDE (ключ ddeexec), но запуск verb через DDE уже устаревшее наследие (Deprecated). Писать это заново незачем.12

Ещё одна частая ошибка — кавычки в командной строке. Если элемент командной строки может содержать пробел, его нужно обернуть в кавычки. Это относится и к пути EXE вроде C:\Program Files\..., и %1 (путь выбранного файла) всегда пишите как "%1". Нельзя гарантировать, что путь файла пользователя не содержит пробела. My Program.exe без кавычек толкуется как «запустить My с аргументом Program.exe».13

Ошибка с кавычками в командной строкеКоманда без кавычек режется по пробелу и ошибочно толкуется как запуск My с аргументом Program.exe, поэтому путь EXE, который может содержать пробел, и %1, обозначающий путь выбранного файла, всегда нужно оборачивать в кавычкирежется по пробелуКоманда без кавычекОшибочно толкуется как запуск другого EXEКоманда в кавычкахЗапускается как задуманоОберните путь EXE в кавычкиВсегда оборачивайте и %1 в кавычки

Рис. 6: Команда без кавычек ошибочно режется по пробелу, поэтому путь EXE и %1 всегда оборачивайте в кавычки.

Механизм только реестра до этой точки (статический verb) можно реализовать, не написав ни одной DLL, и он не рискует сделать Проводник нестабильным. Сама Microsoft неоднократно говорит: «прежде чем писать расширение оболочки, подумайте, хватит ли самого простого статического verb, который закрывает требования».9

4. Классические расширения оболочки ── DLL, которая работает внутри Проводника

4.1. Виды расширений оболочки

Требования, которые статический verb не закрывает — «менять меню динамически в зависимости от выбора», «подменить значок или страницу свойств» — закрывают обработчики расширения оболочки. Основные виды таковы.4

Обработчик Основной интерфейс Что умеет
Обработчик контекстного меню IContextMenu + IShellExtInit Динамически добавлять пункты меню и управлять ими
Обработчик значков / наложение значка IExtractIcon / IShellIconOverlayIdentifier Значок на файл и наложение
Обработчик страницы свойств IShellPropSheetExt Добавить вкладку на страницу свойств
Эскиз / всплывающая подсказка IThumbnailProvider / IQueryInfo Вид эскизов и описание при наведении
Обработчик перетаскивания / copy hook IDropTarget / ICopyHook Вмешиваться при сбросе или копировании/перемещении

Всё это реализовано как классы COM и зарегистрировано в реестре по CLSID. Сама идея COM разобрана в «Что такое COM / ActiveX / OCX — различия и связь».

4.2. Что значит быть внутрипроцессным COM-сервером

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

  • Если расширение падает, Проводник падает вместе с ним. Если оно зависает, правый щелчок замирает на несколько секунд. Ущерб не ограничивается Проводником: он достигает каждого приложения, показавшего диалог открытия файла.
  • Построение меню идёт на потоке UI, поэтому нельзя делать медленную работу вроде доступа к сети или файлового ввода-вывода в момент показа меню.
  • Модель потоков регистрируйте как правило Apartment.
Как сбой внутрипроцессного расширения бьёт по хостуDLL расширения оболочки загружается не только в Проводник, но и в процесс любого приложения, открывшего диалог файлов, поэтому сбой или зависание расширения распространяются на весь процесс-хостзагружается внутри процессазагружается внутри процессаDLL расширения оболочкиПроводникЛюбое приложение, открывающее диалогСбой или зависание распространяютсяНе делать медленную работу при показе

Рис. 7: DLL расширения работает внутри процесса-хоста, поэтому сбой или зависание бьют по хосту целиком.

Разбирая обращение вроде «Проводник зависает, когда открываю определённую папку» или «правый щелчок занимает пять секунд», нередко выясняется, что причина — стороннее расширение оболочки, а не ваше приложение. Как локализовать причину — в главе 8.

4.3. Совпадение разрядности ── в 64-разрядной среде нужна 64-разрядная DLL

Внутрипроцессная DLL должна совпадать по разрядности с процессом, который её загружает. Проводник в 64-разрядной Windows — 64-разрядный процесс, поэтому DLL расширения оболочки, собранная только как 32-разрядная, вообще не загружается и в меню не появляется. Ошибки тоже нет, поэтому это типичная причина «зарегистрировал, а не появляется». Сочетание 32-разрядного тела приложения с 64-разрядной DLL расширения оболочки законно, но нужно следить за тем, что COM-регистрация делится по разрядности (Wow6432Node). Запуск из command у verb — отдельный процесс EXE, поэтому этому ограничению не подлежит (оставить 32-разрядный EXE нормально).

Совпадение разрядности DLL расширения оболочкиЕдинственная DLL расширения оболочки, которую 64-разрядный Проводник может загрузить, — 64-разрядная; только 32-разрядная DLL не появляется в меню и не даёт ошибки; EXE, запускаемый из command у verb, — отдельный процесс и ограничению не подлежитможет загрузитьне может загрузитьотдельный процесс64-разрядный Проводник64-разрядная DLL расширения оболочкиТолько 32-разрядная DLLНе появляется в меню, без ошибкиEXE, запускаемый из verbМожно оставить 32-разрядным

Рис. 8: В 64-разрядный Проводник загружается только 64-разрядная DLL; EXE, запускаемый из verb, этому ограничению не подлежит.

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

Меня часто спрашивают «можно ли писать расширение оболочки на C#», но Microsoft прямо заявляет: писать внутрипроцессное расширение оболочки на управляемом коде (.NET) не рекомендуется и находится вне поддержки.5

Причина — природа расширения, загружаемого в произвольный процесс. Конфликт версий CLR (особенно ниже .NET Framework 4), повторный вход CLR в цикл сообщений в ожидании блокировки и недетерминированное время жизни объектов из-за сборки мусора, которое конфликтует с контрактом счётчика ссылок COM, — структурные причины нестабильности хоста. Часть пунктов смягчена в .NET Framework 4 и новее и в современном .NET, но официальная позиция не изменилась.

Практическое правило простое. Внутрипроцессное расширение пишите на нативном C++. Если нужен управляемый код, сделайте обычный EXE, запускаемый из command у verb, или внепроцессное расширение, работающее в отдельном процессе (обработчик предпросмотра и подобное).5

Решение, допустим ли управляемый кодВнутрипроцессное расширение, работающее внутри Проводника, по правилу пишут на нативном C++; если нужен управляемый код, сделайте обычный EXE, запускаемый из command у verb, или внепроцессное расширение в отдельном процесседанетРаботает внутри процесса?Пишите на нативном C++Управляемый код допустимКонфликт CLR и повторный вход делают хост нестабильнымEXE, запускаемый из verbВнепроцессный предпросмотр

Рис. 9: Внутрипроцессное расширение по правилу — нативный C++; управляемый код ограничен конфигурацией, которая работает в отдельном процессе.

5. Новое контекстное меню Windows 11 ── меню, разделённое на два уровня

5.1. Что произошло

Windows 11 обновила контекстное меню Проводника. Вырезать, копировать и подобное стали рядом значков сверху; «Открыть» и «Открыть с помощью» сгруппировали сверху; команды, которые добавляет приложение, группируются под стандартными командами оболочки. Когда одно приложение добавляет несколько команд, их собирают во всплывающее меню (подменю, flyout) с именем приложения.6

И решающий момент таков. Классические расширения оболочки на IContextMenu не удалили; их отодвинули в старое меню, которое открывается «Показать дополнительные параметры» (Shift+F10) и загружает меню Windows 10 как есть.6 За «меню спрятали» в том начальном обращении как раз и стоит это разделение на два уровня.

Контекстное меню, которое Windows 11 разделила на два уровняСначала при правом щелчке открывается новое меню; там появляются только команды, зарегистрированные через IExplorerCommand и удостоверение пакета; классические расширения IContextMenu отодвинуты в старое меню, открываемое «Показать дополнительные параметры»Показать дополнительные параметры Shift+F10Правый щелчок по файлуНовое меню (Windows 11)Команды IExplorerCommand + удостоверениеСтарое меню (меню Windows 10)Классические расширения IContextMenuНесколько команд собирают во всплывающее меню

Рис. 10: В новое меню попадают только команды IExplorerCommand + удостоверение; классические расширения отодвинуты в старое меню.

5.2. Официальный путь в новое меню ── IExplorerCommand + регистрация в манифесте

Есть один способ поместить свою команду в новое меню. Подготовьте нативную DLL, реализующую интерфейс IExplorerCommand, и объявите COM-сервер и расширение контекстного меню в манифесте пакета MSIX.7

<!-- Манифест пакета (фрагмент) -->
<com:Extension Category="windows.comServer">
  <com:ComServer>
    <com:SurrogateServer DisplayName="Komura commands">
      <com:Class Id="01234567-89AB-CDEF-0123-456789ABCDEF"
                 Path="KomuraCommand.dll" ThreadingModel="STA" />
    </com:SurrogateServer>
  </com:ComServer>
</com:Extension>
<desktop4:Extension Category="windows.fileExplorerContextMenus">
  <desktop4:FileExplorerContextMenus>
    <desktop5:ItemType Type=".kmrpt">
      <desktop5:Verb Id="VerifyReport"
                     Clsid="01234567-89AB-CDEF-0123-456789ABCDEF" />
    </desktop5:ItemType>
  </desktop4:FileExplorerContextMenus>
</desktop4:Extension>

Type у ItemType может задавать конкретное расширение, или * (все файлы), Directory (папки) или Directory\Background (фон папки). Согласуйте DLL с архитектурой Проводника (64 бит / ARM64).7

Сам IExplorerCommand — интерфейс со времён Windows 7; вы реализуете заголовок (GetTitle), значок (GetIcon), состояние включено / отключено / скрыто (GetState) и выполнение (Invoke). Методы вызываются с потока UI, поэтому доступ к сетевым ресурсам запрещён, а методы построения меню должны возвращаться быстро. Тяжёлую работу делайте после Invoke.147

Структура манифеста регистрации в новом менюОбъявление COM-сервера в манифесте MSIX сопоставляет CLSID с DLL, а объявление расширения контекстного меню связывает цель и реализацию через ItemType и Verb, поэтому своя команда появляется в новом менюсопоставляет CLSID с DLLзадаёт через ItemType и VerbМанифест MSIXОбъявление COM-сервераОбъявление расширения менюDLL реализации IExplorerCommandКоманда появляется в новом менюЦель — расширение, все файлы и подобное

Рис. 11: Два объявления в манифесте связывают DLL реализации с целью, и команда появляется в новом меню.

5.3. Вариант для неупакованного приложения ── получить только удостоверение через sparse package

Выход, когда «наше приложение можно распространять только как MSI; MSIX невозможен», — sparse package (MSIX с внешним расположением). Вы подписываете небольшой MSIX, в котором есть только манифест, без тела приложения, и регистрируете его в конце существующего установщика. Тогда приложение получает удостоверение пакета, и регистрация в манифесте выше (то есть появление в новом меню) становится возможной. Доступно начиная с Windows 10 версии 2004; пакету нужна подпись сертификатом, которому доверяют на целевой машине.8

Как получить удостоверение через sparse packageПосле того как существующий установщик разместил тело приложения, регистрация sparse package только с манифестом и внешним расположением даёт приложению удостоверение пакета и делает возможной регистрацию манифеста нового менюСуществующий установщикРазместить тело приложенияSparse packageТолько манифест, без телаЗарегистрировать с внешним расположениемПолучить удостоверение пакетаРегистрация в новом меню становится возможнойНужна доверенная подпись

Рис. 12: Зарегистрируйте sparse package без тела с внешним расположением — и приложение получит удостоверение пакета.

Главное преимущество — не нужно менять установщик; это практичный ответ для приложения, у которого уже есть актив установщика MSI/EXE. Сравнение с полным переходом на MSIX см. также в «Как выбрать способ распространения Windows-приложения — MSI/MSIX/ClickOnce/xcopy/свой updater».

5.4. Как verb сопоставления выглядят в новом меню

Это легко понять неправильно: сопоставления глав 2 и 3 (ProgID и verb) в новом меню по-прежнему работают. Verb по умолчанию при двойном щелчке, «Открыть» и кандидаты «Открыть с помощью» разрешаются из сопоставления и показываются вверху нового меню. Поэтому если нужно только «открывать этим приложением», Windows 11 не требует дополнительной работы. С другой стороны, сопоставление — не универсальное расширение меню, поэтому произвольную свою команду в первый уровень нового меню ставят через IExplorerCommand плюс удостоверение — таково разделение ролей.7

Разделение ролей между сопоставлениями и новым менюСопоставление ProgID и verb в новом меню по-прежнему используется, чтобы разрешить verb по умолчанию, Открыть и Открыть с помощью, и показывается вверху; произвольную свою команду в первый уровень нового меню ставят через IExplorerCommand и удостоверениеСопоставление (ProgID + verb)Разрешить verb по умолчанию и ОткрытьВерх нового менюВ Windows 11 дополнительной работы не нужноПроизвольная своя командаIExplorerCommand + удостоверениеПервый уровень нового меню

Рис. 13: Сопоставления по-прежнему отвечают за разрешение семейства «Открыть» в новом меню; только своя команда требует IExplorerCommand плюс удостоверение.

6. Практическая таблица решения ── какой из трёх вариантов взять

Сводим сказанное в практический выбор из трёх.

Что хотите получить Рекомендуемое средство Как выглядит в Windows 11 Нужная работа и стоимость
(a) Запускать своё приложение двойным щелчком или «Открыть» Сопоставление + статический verb (только регистрация в реестре) Встроено в «Открыть» и «Открыть с помощью» в новом меню Только регистрация в реестре установщиком. Нет DLL, нет дополнительного требования подписи
(b) Поместить свою команду для выбранного файла/папки в новое меню Реализация IExplorerCommand + регистрация в манифесте MSIX. Неупакованному приложению дают удостоверение через sparse package Первый уровень нового меню (несколько команд собирают во всплывающее меню с именем приложения) Нативная C++ DLL + удостоверение пакета + подпись кода
(c) Продолжать использовать существующее классическое расширение IContextMenu Пока оставить как есть (не выбирать для новой разработки) Только сторона старого меню, под «Показать дополнительные параметры» (Shift+F10) Поддерживать 64-разрядную сборку и COM-регистрацию. Планировать поздний переход на (b)

Два пункта суждения. Первое: не тащите (b) или (c) под требование, которое закрывает (a). В момент, когда пишете расширение оболочки, вы берёте ответственность за стабильность Проводника. Второе: (c) лишь «не сломано»; как пользовательский опыт оно остаётся на шаг хуже. Чем чаще команда используется в повседневной работе, тем больше отдача от перехода на (b).

Как выбирать среди трёх вариантовЕсли нужен только запуск двойным щелчком или Открыть, хватит сопоставления и статического verb; чтобы поместить свою команду в новое меню, используйте IExplorerCommand и регистрацию в манифесте MSIX; если нельзя стать MSIX, выдайте удостоверение через sparse package; существующее классическое расширение IContextMenu пока оставьте на стороне старого менюданетдаданетнетХватит Открыть?Сопоставление + статический verbСвоя команда в новом меню?Можете стать MSIX?IExplorerCommand+MSIXУдостоверение через sparse packageПока оставить классическоеТолько сторона старого менюНет DLL, малый риск

Рис. 14: Выбирайте среди статического verb, IExplorerCommand плюс удостоверение и сохранения классического — по требованию.

7. Развёртывание и регистрация на практике ── установщик, sparse package, очистка

7.1. HKLM или HKCU

Согласуйте с формой установщика. Для всех пользователей (размещено под Program Files, права администратора) — HKLM\Software\Classes; установка на пользователя (без повышения) — HKCU\Software\Classes. Смешаете — получите обращение «у A открывается, у B нет». Для расширения оболочки с регистрацией CLSID Reg-Free COM — убирающий саму регистрацию в реестре — годится для COM внутри приложения, но неприменим к расширению оболочки, которое загружает Проводник, поэтому нужна прямая регистрация («Что такое Reg-Free COM — как использовать COM без регистрации»).

7.2. После изменения уведомите ── SHChangeNotify

После регистрации, изменения или удаления сопоставления уведомите о событии SHCNE_ASSOCCHANGED через SHChangeNotify. Пропустите это — и Проводник может не заметить изменение до перезагрузки.110

// Вызвать один раз после смены сопоставлений, например из пользовательского действия установщика
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);

7.3. Регистрация и снятие sparse package

Регистрация и снятие sparse package — работа установщика. Регистрируйте после размещения файлов; снимайте до удаления файлов.8

# При установке: после размещения файлов зарегистрировать папку установки как внешнее расположение
Add-AppxPackage -Path "C:\Program Files\KomuraSoft\KomuraReport.identity.msix" `
                -ExternalLocation "C:\Program Files\KomuraSoft"

# При удалении: снять регистрацию пакета до удаления файлов
Remove-AppxPackage <полное имя пакета>

На что смотреть: Add-AppxPackage регистрирует для пользователя, который его выполнил. Если вызвать из пользовательского действия MSI на всю машину под LocalSystem, удостоверение не выдаётся установившему пользователю, поэтому настраивают выполнение под олицетворением пользователя. Даже тогда регистрация под олицетворением — только для пользователя, выполнившего эту установку. На ПК с несколькими пользователями у других и у созданных позже пользователей нет удостоверения пакета, и команда не появляется в новом меню. Чтобы каждый пользователь мог пользоваться, дайте механизм вроде проверки своей регистрации пакета при первом запуске и регистрации, если её нет (регистрация на пользователя), и включите снятие у каждого пользователя с регистрацией в план удаления. Чтобы регистрация манифеста вступила в силу, может понадобиться перезапуск Проводника (или выход из системы).7

Порядок регистрации и снятия sparse packageПри установке регистрируйте sparse package после размещения файлов; при удалении снимайте регистрацию до удаления файлов; следите за тем, что регистрация действует только для пользователя, который её выполнилУстановкаРазместить файлыЗарегистрировать sparse packageУдалениеСнять регистрацию пакетаУдалить файлыРегистрация действует только для текущего пользователя

Рис. 15: Регистрируйте после размещения файлов, снимайте до удаления и следите за тем, что регистрация — на текущего пользователя.

7.4. Очистка при удалении ── что удалять и что оставлять

У очистки при удалении есть ясная линия официального руководства.1

  • Удалять: весь свой ключ ProgID, регистрацию Capabilities/RegisteredApplications, регистрацию CLSID расширения оболочки, sparse package (Remove-AppxPackage).
  • Оставлять: значение по умолчанию ключа расширения (.kmrpt). Официальная рекомендация — не удалять его, даже если оно всё ещё указывает на свой ProgID. После установки трудно судить, не забрало ли другое приложение значение по умолчанию, а Windows просто игнорирует незарегистрированный ProgID значения по умолчанию, так что оставлять его не вредно.
  • Вызовите SHChangeNotify(SHCNE_ASSOCCHANGED) и в конце очистки.

Большинство проблем «удалили, а в меню ещё остатки» — пробел в этой очистке.

Как чистить регистрацию при удаленииПри удалении удаляете свой ключ ProgID, регистрацию CLSID и sparse package; оставляете значение по умолчанию ключа расширения, потому что незарегистрированный ProgID игнорируется; в конце очистки уведомляете об изменении через SHChangeNotifyУдалениеУдалитьОставитьРегистрация ProgID и CLSIDSparse packageЗначение по умолчанию ключа расширенияНезарегистрированный ProgID игнорируетсяВ конце уведомить через SHChangeNotify

Рис. 16: Удалите свою регистрацию, оставьте значение по умолчанию ключа расширения и в конце очистки уведомите об изменении.

8. Диагностика ── нет, дубль, тяжело

8.1. Не появляется в меню

Локализуйте в таком порядке.

  1. Какое меню смотрите: регистрация в классическом стиле появляется только на стороне старого меню под Shift+F10. Сначала проверьте оба.
  2. Разрядность: только 32-разрядная DLL расширения оболочки не загружается в 64-разрядный Проводник (раздел 4.3).
  3. Место регистрации: HKLM/HKCU, путаница Wow6432Node. Подтвердите фактический ключ через reg query.
  4. Регистрация пакета: для нового меню подтвердите наличие через Get-AppxPackage, доверие сертификата подписи и путь -ExternalLocation, затем перезапустите Проводник.7
  5. Пропущенное уведомление: если забыли SHChangeNotify, это видно по тому, помогает ли перезапуск Проводника.
Порядок диагностики, когда не появляется в менюНачните с подтверждения, какое меню смотрите, затем проверьте разрядность DLL, место регистрации в реестре, регистрацию пакета и подпись, и пропущенный SHChangeNotify, в этом порядкеПодтвердить, какое меню, старое или новоеПодтвердить разрядность DLLПодтвердить место регистрации HKLM и HKCUПодтвердить регистрацию пакета и подписьРаспознать пропущенное уведомление перезапуском

Рис. 17: Когда «не появляется», проверяйте в порядке меню, которое смотрите, разрядность, место регистрации, регистрация пакета, пропущенное уведомление.

8.2. Появляется дважды или не исчезает

Типичные причины — одновременно живут классическая регистрация в реестре и регистрация в манифесте, пробел в очистке при удалении (раздел 7.4) или остатки ProgID старой версии. Если дважды только в старом меню — думайте об остатках; если на старом и новом — о сосуществовании двух регистраций.

Диагностика двойного отображенияДважды только в старом меню указывает на остатки вроде пробела в очистке или старого ProgID; дважды на старом и новом указывает на сосуществование классической регистрации в реестре и регистрации в манифестетолько старое менюстарое и новоеГде появляется дважды?ОстаткиСосуществованиеПробел в очистке или оставленный старый ProgIDКлассическая регистрация в реестре сосуществует с новой

Рис. 18: Дважды только в старом меню указывает на остатки; дважды на старом и новом — на сосуществование.

8.3. Проводник тяжёлый или падает

Когда правый щелчок медленный или определённая папка падает, сначала составьте опись установленных расширений оболочки. Перечислите расширения не от Microsoft инструментом вроде ShellExView от NirSoft, временно отключите подозрительные и найдите виновную DLL методом половинного деления. При сбое подсказкой служит и «Faulting module» в Просмотре событий. Если причиной было своё расширение, подозревайте синхронный ввод-вывод или доступ к сети на пути построения меню (разделы 4.2 и 5.2).

Поиск виновной DLL, когда тяжело или падаетПеречислите расширения оболочки не от Microsoft в ShellExView, временно отключите подозрительные и найдите виновную DLL методом половинного деления; при сбое подсказкой служит и faulting module в Просмотре событийОпись расширений оболочкиПеречислить не от MicrosoftВременно отключить и половинное делениеНайти виновную DLLПри сбоеПроверить faulting module

Рис. 19: Временно отключите расширения не от Microsoft и ищите половинным делением; при сбое используйте и Просмотр событий.

8.4. Для проверки удобна Windows Sandbox

Проверка интеграции с оболочкой строится на подтверждении «установить в чистой среде → поработать → удалить → остатков ноль». Здесь удобна Windows Sandbox (Pro/Enterprise/Education): каждый запуск за несколько секунд поднимает совершенно новую одноразовую Windows, поэтому тесты регистрации и очистки установщика можно прогонять сколько угодно. Закроете — всё исчезнет, поэтому подходит и для расследования остаточного реестра.15

9. Итог

  • Сопоставление файлов — трёхступенчатая схема «ключ расширения → ProgID → verb», а HKCR — объединённое представление Classes из HKLM/HKCU. Место записи указывайте явно и всегда оборачивайте %1 в кавычки.
  • Приложение по умолчанию выбирает пользователь, из программы его не сменить. Работа установщика — правильно зарегистрироваться как кандидат.
  • Классическое расширение оболочки — внутрипроцессная COM DLL, загружаемая в Проводник. Сбой или задержка бьют по целому; нужны 64 бита; управляемый код не поддерживается; правило — реализация на нативном C++.
  • В Windows 11 контекстное меню разделено на два уровня. Чтобы поместить свою команду в новое меню, нужны IExplorerCommand плюс манифест MSIX; классический IContextMenu отодвинут на сторону «Показать дополнительные параметры».
  • Для приложения, которое нельзя упаковать в MSIX, получить удостоверение через sparse package (MSIX с внешним расположением) — практичный ответ.
  • Если нужно только «открыть этим приложением», сопоставления и статического verb по-прежнему достаточно. Начинать с самого простого средства — и официальная рекомендация.
  • После регистрации, изменения или удаления уведомите через SHChangeNotify; при удалении удалите ProgID, но оставьте значение по умолчанию ключа расширения. Для проверки удобна Windows Sandbox.

Если замена ПК на Windows 11 заставила заметить, что «меню спрятали», сначала подтвердите, какой это из (a), (b) и (c) в таблице решения главы 6. Масштаб работы должно быть видно на месте.

Похожие статьи

Смежные области консультирования

Компания KomuraSoft LLC занимается проектированием и реализацией сопоставления файлов, контекстных меню и расширений оболочки для бизнес-приложений; поддержкой нового контекстного меню Windows 11 (переход на IExplorerCommand, внедрение sparse package); проверкой регистрации и очистки существующего установщика; и расследованием причины, когда Проводник тяжёлый или падает. Можно начать с решения, что делать с «меню, спрятанным под Показать дополнительные параметры».

Справочные ссылки

  1. Microsoft Learn, File Types. О структуре ключа расширения, указывающего на ProgID; OpenWithProgIds; делении регистрации между HKLM/HKCU\Software\Classes; вызове SHChangeNotify(SHCNE_ASSOCCHANGED) после смены сопоставления; и удалении ProgID при удалении с оставлением значения по умолчанию ключа расширения. ↩ ↩2 ↩3 ↩4 ↩5

  2. Microsoft Learn, HKEY_CLASSES_ROOT Key. О том, что HKEY_CLASSES_ROOT — объединённое представление HKLM\Software\Classes и HKCU\Software\Classes; определения на стороне пользователя имеют приоритет над машинными; и правилах распределения при записи. ↩ ↩2

  3. Microsoft Learn, Windows app defaults platform. О том, что смена приложения по умолчанию рассчитана только на системный интерфейс Параметры; данные пользовательских настроек обфусцированы и защищены от записи драйвером-фильтром (UCPD.sys); смена на основе реестра не поддерживается; и в управляемой среде используют групповую политику / политику MDM. ↩ ↩2

  4. Microsoft Learn, Working with Shell Extensions. О видах обработчиков расширений оболочки; расширении как внутрипроцессной COM DLL, загружаемой в Проводник (и в процессы, хостящие оболочку), так что сбой или зависание бьют по Проводнику целиком; регистрации с ThreadingModel=Apartment; и рассмотрении более простой альтернативы до расширения оболочки. ↩ ↩2 ↩3

  5. Microsoft Learn, Guidance for Implementing In-Process Extensions. О том, что Microsoft не рекомендует и не поддерживает внутрипроцессную реализацию расширения оболочки на управляемом коде; причинах, включая конфликт версий CLR, повторный вход и недетерминированное время жизни объектов; и допустимости управляемого кода для внепроцессного расширения (обработчик предпросмотра или запуск из shell\verb\command). ↩ ↩2 ↩3

  6. Windows Developer Blog, Extending the Context Menu and Share Dialog in Windows 11. О замысле нового контекстного меню Windows 11; расширении через IExplorerCommand плюс удостоверение приложения; размещении «Открыть» и «Открыть с помощью» сверху; сборе нескольких команд во всплывающее меню с именем приложения; и классических расширениях IContextMenu, загружаемых как меню Windows 10 под «Показать дополнительные параметры» (Shift+F10). ↩ ↩2 ↩3

  7. Microsoft Learn, Add a File Explorer context menu command to a packaged desktop app. О том, что регистрация в новом контекстном меню Windows 11 делается реализацией IExplorerCommand плюс windows.comServer плюс объявлением манифеста desktop4:FileExplorerContextMenus; ItemType может задавать *, Directory или Directory\Background; согласовании архитектуры DLL; сохранении методов построения меню быстрыми; покрытии неупакованного приложения через sparse package; иногда нужном перезапуске Проводника, чтобы регистрация вступила в силу; и том, что сопоставление файлов — не универсальное расширение меню. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8

  8. Microsoft Learn, Grant package identity by packaging with external location. О получении удостоверения пакета регистрацией пакета с внешним расположением (sparse package) без смены существующего установщика; доступности начиная с Windows 10 версии 2004; и функциях Windows, требующих удостоверения (регистрация в контекстном меню, уведомления и подобное), которые становятся доступны. ↩ ↩2 ↩3

  9. Microsoft Learn, Choosing a Static or Dynamic Shortcut Menu Method. О выборе самого простого метода статического verb, который закрывает требования; IContextMenu как самом мощном, но и самом сложном и отнесённом к нерекомендуемой стороне; и IExplorerCommand/IExplorerCommandState как рекомендуемом методе. ↩ ↩2

  10. Microsoft Learn, SHChangeNotify function. О том, как поднять событие SHCNE_ASSOCCHANGED, уведомляющее систему о смене сопоставления файлов, и как использовать его, чтобы оболочка заметила изменение. ↩ ↩2

  11. Microsoft Learn, Application Registration. О том, что регистрация исполняемого файла через подраздел App Paths рекомендуется; роли подраздела Applications; регистрации verb через SystemFileAssociations; и приоритете ProgID и связанных сведений при смене приложения по умолчанию. ↩

  12. Microsoft Learn, Creating Shortcut Menu Handlers. О способе регистрации статического verb; порядке определения verb по умолчанию (значение по умолчанию → первый verb → Open → Open With); отображаемых именах стандартных verb, которые даёт ОС; расширенных verb через Extended; сопоставлении с командами DDE, которое Deprecated; и оговорках перенаправления WOW64 в 64-разрядной среде. ↩ ↩2 ↩3

  13. Microsoft Learn, Verbs and File Associations. О том, что verb — действие, используемое и ShellExecuteEx; элементы командной строки, которые могут содержать пробел, нужно оборачивать в кавычки, а “%1” всегда писать в кавычках; и регистрации процедуры по умолчанию под HKCR\Applications. ↩

  14. Microsoft Learn, IExplorerCommand interface. О составе методов GetTitle, GetIcon, GetState, Invoke, EnumSubCommands и подобных; методах, вызываемых на потоке UI, поэтому они не должны общаться с сетевыми ресурсами; и доступности начиная с Windows Vista. ↩

  15. Microsoft Learn, Windows Sandbox. О возможности за несколько секунд запустить одноразовую изолированную среду Windows, обо всех изменениях, отбрасываемых при закрытии, пригодности для тестирования ПО и проверки установщика, и доступности на Pro/Enterprise/Education. ↩

Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.

Эти страницы показывают тему статьи в более широком контексте услуг и решений.

Статья напрямую связана со следующими услугами.

Частые вопросы

Вопросы, которые часто возникают при консультациях по теме статьи.

Почему в Windows 11 пункт контекстного меню нашего приложения виден только в «Показать дополнительные параметры»?
Потому что в Windows 11 контекстное меню Проводника разделено на два уровня — новое и старое. В новое меню попадают только команды, которые реализуют интерфейс IExplorerCommand и зарегистрированы в манифесте пакета MSIX (то есть имеют удостоверение пакета). Классические расширения оболочки на IContextMenu отодвинуты в старое меню, которое открывается через «Показать дополнительные параметры» (Shift+F10). Само расширение не сломано и пока продолжает работать, но чтобы пункт появился в новом меню, нужна миграция на IExplorerCommand и либо упаковка в MSIX, либо выдача удостоверения через sparse package.
Может ли установщик назначить наше приложение приложением по умолчанию для файла (тем, что открывается двойным щелчком)?
Нет. Приложение по умолчанию выбирает пользователь, и Windows не поддерживает смену приложения по умолчанию ниоткуда, кроме системного интерфейса Параметры. Данные UserChoice, в которых хранится выбор каждого пользователя, обфусцированы, а драйвер-фильтр (UCPD.sys) дополнительно блокирует запись из приложений. Установщик может зарегистрировать ProgID и verb, добавить себя в OpenWithProgIds, чтобы появиться кандидатом в «Открыть с помощью», и направить пользователя на страницу приложений по умолчанию. Правильная реализация — не забирать значение по умолчанию, а подготовиться к тому, чтобы вас выбрали.
Можно ли писать расширение оболочки на управляемом коде, например на C#?
Microsoft прямо заявляет: внутрипроцессное расширение оболочки (обработчик контекстного меню, обработчик значков и подобное) на управляемом коде не рекомендуется и не поддерживается. Расширение загружается в Проводник и в процесс любого приложения, открывшего общее диалоговое окно файлов, поэтому конфликт версий CLR, повторный вход и недетерминированное время жизни объектов делают хост нестабильным. Правило — реализация на нативном C++. Обычный EXE, который запускается из command у verb, или внепроцессное расширение вроде обработчика предпросмотра, работающее в отдельном процессе, на управляемом коде допустимы.
Что такое sparse package (MSIX с внешним расположением)?
Небольшой пакет MSIX, в котором нет файлов приложения, только манифест (сведения об удостоверении). Для приложения, установленного обычным установщиком (MSI, Inno Setup и подобными), его регистрируют через Add-AppxPackage с -ExternalLocation, указывая папку установки. Приложение получает удостоверение пакета и может пользоваться функциями, которые его требуют: регистрацией в новом контекстном меню Windows 11 и всплывающими уведомлениями. Доступно начиная с Windows 10 версии 2004; пакету нужна подпись кода сертификатом, которому доверяет целевая машина. Это практичный вариант, когда нужна поддержка нового меню без перевода всей поставки на MSIX.
Что делать, если пункт контекстного меню появляется дважды или не исчезает?
Сначала локализуйте причину: пункт виден в новом меню или в старом («Показать дополнительные параметры»). Типичное дублирование — одновременно живут классическая регистрация в реестре и регистрация в манифесте MSIX либо после удаления осталась регистрация ProgID или CLSID расширения. После смены сопоставления подозревайте также пропущенный SHChangeNotify(SHCNE_ASSOCCHANGED); сразу после регистрации пакета — что Проводник не перезапустили. Если это не помогает, временно отключите расширения не от Microsoft в ShellExView и найдите виновную DLL методом половинного деления.

Об авторе

Страница с профилем автора статьи.

Го Комура

Представитель KomuraSoft LLC

Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.

Публичные ссылки

Вернуться в блог