2025, Oct 16 01:16

Добавляем пункт контекстного меню для .url через HKCU\Software\Classes\InternetShortcut

Добавляем пункт контекстного меню для .url в Windows через HKCU\Software\Classes (InternetShortcut). Учитываем ProgId/UserChoice. Всё без прав администратора.

Добавить пункт контекстного меню для конкретного пользователя в Windows обычно несложно: прописываете глагол (verb) под HKCU, и оболочка его подхватывает. Для обычных файлов, папок и ярлыков .lnk это работает стабильно. Но с интернет‑ярлыками (.url) всё устроено иначе — и здесь начинаются сложности.

Проблема в коде

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

import winreg as wreg
key_path = r"SOFTWARE\Classes\*\shell\NewItem"
with wreg.CreateKey(wreg.HKEY_CURRENT_USER, key_path) as root_handle:
    wreg.SetValueEx(root_handle, 'MUIVerb', 0, wreg.REG_SZ, 'New Item')
    with wreg.CreateKey(root_handle, 'command') as action_key:
        wreg.SetValue(action_key, '', wreg.REG_SZ, r'"C:\...\app.exe" "%1"')

В такой схеме путь SOFTWARE\Classes\*\shell\NewItem нацеливает пункт на «все файлы», SOFTWARE\Classes\Directory\shell\NewItem — на папки, а SOFTWARE\Classes\lnkfile\shell\NewItem — на ярлыки .lnk. Попытка применить тот же подход к интернет‑ярлыкам через SOFTWARE\Classes\InternetShortcut\shell или SOFTWARE\Classes\.url\shell\NewItem не даёт ожидаемого эффекта.

Что на самом деле происходит

Windows хранит системный каталог регистраций типов файлов в HKEY_CLASSES_ROOT. Ветвь HKCU\Software\Classes накладывается поверх него, предоставляя пользовательские переопределения. Чтение выполняется как объединение, а запись в HKCR без прав администратора ограничена; зато HKCU\Software\Classes доступна для записи на уровне пользователя.

Конкретно для .url системная регистрация уже существует, а пользовательского аналога часто нет. Поэтому добавление записей только в HKCU может внешне ничего не менять. Здесь важен класс под названием InternetShortcut. Ещё один практический нюанс: фактическую ассоциацию может определять ProgId, хранящийся в HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.url\UserChoice. Это значение может быть, например, IE.AssocFile.URL, ChromeHTML, FirefoxURL, OperaHTML и т. п., и от него зависит обработка .url.

Есть и поведенческая особенность: для других типов файлов дополнительные обработчики обычно видны в интерфейсе «Открыть с помощью». Интернет‑ярлыки по умолчанию этот пункт не показывают, а включить его можно только с правами администратора, что описано здесь: https://www.elevenforum.com/t/add-or-remove-open-with-context-menu-to-url-files-in-windows-11.11958/.

Куда двигаться

Рабочий путь — создать пользовательское переопределение для класса InternetShortcut в HKCU\Software\Classes. Это тот самый пользовательский слой, который дополняет или перекрывает HKEY_CLASSES_ROOT. Нужно ли дополнительно переопределять расширение в верхнем регистре .URL для пользователя, копировать системные подразделы InternetShortcut перед их расширением или достаточно просто добавить глагол под новым ключом класса — зависит от окружения. Базовый класс — InternetShortcut; а реальные поддеревья в HKEY_CLASSES_ROOT\InternetShortcut могут различаться между версиями Windows и в зависимости от настроенного браузера, поэтому сперва безопаснее посмотреть, что именно есть в вашей системе, через regedit.exe.

Пример записи на уровне пользователя

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

import winreg as wreg
user_class_path = r"SOFTWARE\Classes\InternetShortcut\shell\NewItem"
with wreg.CreateKey(wreg.HKEY_CURRENT_USER, user_class_path) as cls_key:
    wreg.SetValueEx(cls_key, 'MUIVerb', 0, wreg.REG_SZ, 'New Item')
    with wreg.CreateKey(cls_key, 'command') as cmd_node:
        wreg.SetValue(cmd_node, '', wreg.REG_SZ, r'"C:\...\app.exe" "%1"')

Если фактический обработчик .url на вашей машине задаётся ProgId из ...\FileExts\.url\UserChoice, учитывайте, что это влияет на появление нового пункта. Эталонную структуру класса InternetShortcut в системе можно посмотреть по адресу HKEY_CLASSES_ROOT\InternetShortcut; значения там могут отличаться от системы к системе.

Почему это важно

Интеграция .url в контекстное меню находится на стыке системных классов, пользовательских переопределений и текущей ассоциации браузера. Запись только в HKCU — правильная практика для установок на пользователя, но с интернет‑ярлыками легко промахнуться по точке входа или рассчитывать на интерфейс, которого по умолчанию нет. Понимание того, что HKCU\Software\Classes — это накладка на HKCR, объясняет, почему изменения в одной ветке могут не проявляться сразу и почему права могут блокировать правки в HKCR.

Выводы

Определите нужный класс — InternetShortcut — и добавляйте свой пункт под HKCU\Software\Classes, чтобы не требовать прав администратора. Проверьте содержимое системного класса в HKEY_CLASSES_ROOT и помните, что на детали влияют настройки браузера и версия ОС. Если ассоциация для .url управляется ProgId в пользовательском ...\UserChoice, это тоже меняет картину. Там, где «Открыть с помощью» обычно показывает обработчики, .url ведёт себя иначе, и включение этого интерфейса требует изменений с правами администратора.

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

Статья основана на вопросе на StackOverflow от H.P. и ответе cyberbrain.