Современный способ зарегистрировать/отменить регистрацию типа файла с моим собственным приложением для текущего пользователя в Windows10?

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

  1. @AndreasRejbrand опубликовал здесь принятое решение: the-current-user">Как связать программу с типом файла, но только для текущего пользователя?
    a) Не существует дополнительного способа ОТМЕНИТЬ РЕГИСТРАЦИЮ типа файла.
    b ) Непонятно, что означает 'MyAppDataFile'.
    c) Нет практических примеров использования.

  2. Библиотека DSiWin32 содержит методы DSiRegisterUserFileAssoc и DSiUnregisterUserFileAssoc:
    а) procedure DSiRegisterUserFileAssoc(const extension, progID, description, defaultIcon, openCommand: string);
    аа) Непонятно, что означает параметр progID.
    аб) Непонятно, как передать параметр defaultIcon.
    ac) Непонятно, как передать параметр openCommand.
    b) procedure DSiUnregisterUserFileAssoc(const progID: string);
    ba) Непонятно, что означает параметр progID и как его форматировать.
    c ) было бы неплохо иметь пример практического использования.

Кстати, это код от @AndreasRejbrand:

with TRegistry.Create do
  try
    RootKey := HKEY_CURRENT_USER;
    if OpenKey('\Software\Classes\.myfile', true) then
      WriteString('', 'MyAppDataFile');
    if OpenKey('\Software\Classes\MyAppDataFile', true) then
      WriteString('', 'My Very Own Text File Type');
    if OpenKey('\Software\Classes\MyAppDataFile\DefaultIcon', true) then
      WriteString('', 'C:\WINDOWS\notepad.exe');
    if OpenKey('\Software\Classes\MyAppDataFile\shell\open\command', true) then
      WriteString('', 'C:\WINDOWS\notepad.exe "%1"');
  finally
    Free;
  end;
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);

Может ли кто-нибудь предоставить четкие и надежные примеры практического использования для обоих подходов? Какой лучше?

РЕДАКТИРОВАТЬ: с практическими примерами ИСПОЛЬЗОВАНИЯ я имею в виду: процедура/функция с примерными параметрами.


person user1580348    schedule 09.05.2021    source источник
comment
Разве это не задокументировано в MSDN?   -  person David Heffernan    schedule 09.05.2021
comment
1a) Противоположностью создания ключей реестра является их удаление, не так ли? б) Это просто внутреннее имя для типа файла. Может быть ContosoRichTextFile, LitwareVideoFile или SuperappSettingsFile. Или User1580348StarTrekSimulatorStarshipModelFile. Только он должен быть уникальным. в) Разве мой фрагмент кода и связанное с ним описание не являются практическим примером? :) Тем не менее, это старый подход. Вероятно, современный подход более сложен.   -  person Andreas Rejbrand    schedule 10.05.2021
comment
Я думаю, что официальный современный подход описан здесь: docs.microsoft.com/en-us/windows/win32/shell/   -  person Andreas Rejbrand    schedule 10.05.2021
comment
Предположим, вы создали формат файла для модели космического корабля для симулятора Star Trek. Тогда вы можете использовать для него расширение .starship, поэтому первый ключ — .starship, и вы можете использовать идентификатор user1580348starship. Затем вы даете ему описание, скажем, Starship model, и указываете значок, который будет использоваться для таких файлов, а также приложение, которое должно открывать их при двойном щелчке. Довольно прямолинейно, не так ли?   -  person Andreas Rejbrand    schedule 10.05.2021
comment
Какой лучше? Они точно такие же. Если вы посмотрите на исходный код DSiRegisterUserFileAssoc, вы увидите, что он делает то же самое, что и мой код. github.com/gabr42/OmniThreadLibrary/blob/   -  person Andreas Rejbrand    schedule 10.05.2021
comment
Если вы хотите увидеть примеры записей реестра типов файлов, вы можете посмотреть в своем собственном реестре (Win+R, regedit, Enter).   -  person Andreas Rejbrand    schedule 10.05.2021
comment
Удалите только прогид, чтобы снять регистрацию, вот что предлагает MS. Вы избавляете себя от необходимости проверять, указывают ли расширения по-прежнему на ваш progid или их заменила другая программа.   -  person Sertac Akyuz    schedule 10.05.2021
comment
Чтобы настроить ассоциацию файлов в проводнике, щелкните правой кнопкой мыши и выберите «Открыть с помощью...», затем установите флажок «Всегда использовать это приложение». Если вы хотите сломать ассоциацию файлов, это немного странно. Вы хотите сделать копию любого EXE-файла, а затем щелкнуть правой кнопкой мыши файл данных и сказать, чтобы всегда открывать его с помощью КОПИИРОВАННОГО EXE-файла. Сделайте это для всех расширений файлов, которые вы хотите разъединить. Затем удалите этот скопированный EXE-файл. Это обновит записи реестра для выбранных расширений. Они не столько удаляются, сколько отсоединяются от приложения, которое их открывает.   -  person David    schedule 10.05.2021
comment
@SertacAkyuz Вот что, по-видимому, делает DSiUnregisterUserFileAssoc: DSiKillRegistry('\Software\Classes\' + progID, HKEY_CURRENT_USER);   -  person user1580348    schedule 10.05.2021
comment
Когда я дважды щелкаю файл .TXT в проводнике Windows, он открывается в Блокноте. Но в Computer\HKEY_CURRENT_USER\Software\Classes\.txt я не нахожу ссылки на Блокнот: есть только OpenWithList, который полностью отличается от того, что я вижу, когда я вызываю подменю «Открыть с помощью» файла .TXT в проводнике. Я также просмотрел ключи \Software\Classes\.txt других корней реестра, но не нашел никаких ссылок на Блокнот. Итак, как это будет работать, когда я попытаюсь зарегистрировать новый формат текстового файла (например, .MyCustomText) для Блокнота, следуя коду @AndreasRejbrand?   -  person user1580348    schedule 10.05.2021


Ответы (1)


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

Предположим, вы хотите, чтобы все файлы с расширением .stext назывались Super Text File в Проводнике, открывались с помощью C:\Program Files\Super Editor\superedit.exe и имели значок C:\Program Files\Super Editor\docicon.ico, тогда вы должны использовать следующий код:

with TRegistry.Create do
  try
    RootKey := HKEY_CURRENT_USER;
    if OpenKey('\Software\Classes\.stext', true) then
      WriteString('', 'SuperTextFile');
    if OpenKey('\Software\Classes\SuperTextFile', true) then
      WriteString('', 'Super Text File');
    if OpenKey('\Software\Classes\SuperTextFile\DefaultIcon', true) then
      WriteString('', 'C:\Program Files\Super Editor\docicon.ico');
    if OpenKey('\Software\Classes\SuperTextFile\shell\open\command', true) then
      WriteString('', '"C:\Program Files\Super Editor\superedit.exe" "%1"');
  finally
    Free;
  end;
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);

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

Если вместо этого вы хотите открыть файлы в Блокноте, используйте путь к notepad.exe вместо последнего WriteString.

Возможно, это не самый сложный подход (вероятно, это подход Win 9x), но он все еще работает, не так ли? И я был бы удивлен, если бы он не оставался в силе для всего будущего настольной платформы Win32.

Процедура DSiRegisterUserFileAssoc делает точно то же самое. как в приведенном выше коде, поэтому оба метода полностью эквивалентны.

Все подробности о состоянии дел см. в документация.

person Community    schedule 10.05.2021
comment
Winapi.ShlObj.SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0); не работает. Последние два параметра должны быть nil: Winapi.ShlObj.SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil); - person user1580348; 10.05.2021
comment
С настройками компилятора по умолчанию он работает и ведет себя точно так же. Но вы правы, что nil более семантически точен. - person Andreas Rejbrand; 10.05.2021
comment
Что вы подразумеваете под настройками компилятора по умолчанию? Я не знаю об установленных специальных настройках компилятора. Моя среда разработки Delphi — 10.4.2 в Windows 10 x64. Проект представляет собой 32-разрядное приложение VCL, созданное в среде IDE с помощью File->New->Windows VCL Application Delphi. - person user1580348; 10.05.2021
comment
Извините, теперь я понял, что это было только ПРЕДУПРЕЖДЕНИЕ компилятора. Он также компилируется с 0 вместо nil. - person user1580348; 10.05.2021
comment
Используя описанный выше метод, я связал расширение .PNG с моим новым графическим приложением. Ассоциация с изображением сработала. Описание файла PNG ДО ТОГО, как было IrfanView PNG File. Оно изменилось на мое новое описание PNG File только после перезагрузки Windows. Однако при двойном щелчке файла .PNG в Windows он всегда открывается в другом средстве просмотра изображений, а не в моем графическом приложении. Конечно, путь к exe заключен в двойные кавычки. И загрузка файла изображения в моем приложении путем передачи файла в качестве параметра, конечно же, работает. - person user1580348; 10.05.2021
comment
Многие программы конкурируют за расширение .PNG. Вероятно, вам больше повезет с .ujy-map или чем-то еще. Либо вы сделали что-то не так, либо вам действительно нужно использовать более необычный подход, по крайней мере, для таких распространенных расширений в Windows 10. Поскольку я использую Windows 7, я не могу проверить поведение в Windows 10. - person Andreas Rejbrand; 10.05.2021
comment
Извините, снова моя ошибка: поскольку я всегда использую Directory Opus в качестве замены File Explorer, файлы .PNG, дважды щелкнутые в Opus, всегда открываются в средстве просмотра Opus. При двойном щелчке файлов .PNG в проводнике Windows они теперь правильно открываются в моем приложении. - person user1580348; 10.05.2021
comment
Другими словами, progID — это ИДЕНТИФИКАТОР, который работает как ССЫЛКА между ключами реестра, каждый из которых ссылается на свойство определенного формата одного файла. Правильно ли это определение? - person user1580348; 11.05.2021
comment
Регистрация формата файла работает как с кодом @AndreasRejbrand, так и с DSiRegisterUserFileAssoc. НО DSiUnregisterUserFileAssoc НЕ работает, даже в повышенном режиме (запустив программу от имени Администратора). Итак, как я могу ОТМЕНИТЬ зарегистрированный формат файла? (Я подозреваю, что приложения Microsoft, зарегистрированные под .ico\OpenWithProgrids, не позволяют удалить ключ?) - person user1580348; 13.05.2021
comment
@ user1580348: В каком смысле это не работает? Как правило, ассоциации файлов принадлежат пользователю, и пользователь может изменить их любым способом в любое время. - person Andreas Rejbrand; 13.05.2021
comment
В каком смысле не работает? Ответ: Ключ progID UGAICOFile не удаляется из реестра (как и должно быть)! И двойной щелчок по файлу .ICO в проводнике по-прежнему загружает мое приложение! Пожалуйста, посмотрите на мой новый вопрос здесь: stackoverflow.com/questions/67519443/ - person user1580348; 13.05.2021