Правильное создание ассоциаций файлов в Windows
На днях столкнулся с интересным багом в своей программе.
При попытке зарегистрировать ассоциации файлов от обычного пользователя возникали ошибка, а от администратора всё происходило нормально. Такая закономерность подсказывает что дело в правах доступа к веткам реестра. И оно оказалось именно так!
Смотрим: на большинстве форумов и статей на сайтах предлагается записывать в HKEY_CLASSES_ROOT. Если посмотреть в реестре, то да, там все наши ассоциации файлов. Но не привилегированному пользователю туда писать НЕЛЬЗЯ.
Дальше я пошёл на MSDN и вот что там нашёл — msdn.microsoft.com/en-us/library/ms724475.aspx.
Теперь всё стало на свои места. Эта ветка осталась для совместимости со старым софтом. Напрямую писать в неё может только админ. А для всего остального есть 2 другие ветки:
HKEY_LOCAL_MACHINE\Software\Classes — для ассоциаций по-умолчанию
HKEY_CURRENT_USER\Software\Classes — и для пользовательских.
Бинго! Вот он заветный раздел. Сюда мы будем и писать. Кстати для быстрого перехода в эту ветку можно использовать функцию RegOpenUserClassesRoot.
Кажется на этом можно и остановиться, но нет. Мы же не такие.
Вернёмся к HKEY_CLASSES_ROOT. Кто дочитал документацию на MSDN понял, а для остальных поясню как там что-то появляется.
Это очень легко: HKEY_LOCAL_MACHINE\Software\Classes + HKEY_CURRENT_USER\Software\Classes. Вот так. Спросите как тогда админ то может туда записывать? Да просто, он пишет в HKEY_LOCAL_MACHINE\Software\Classes. Но если такой ключ есть в ветке HKEY_CURRENT_USER\Software\Classes, то запишет в неё.
А мораль тут такова: не верь всему, что написано не в официальной документации.
P.S.: Кину сюда кусок класса для работы с файловыми ассоциациями в Delphi 7.
При попытке зарегистрировать ассоциации файлов от обычного пользователя возникали ошибка, а от администратора всё происходило нормально. Такая закономерность подсказывает что дело в правах доступа к веткам реестра. И оно оказалось именно так!
Смотрим: на большинстве форумов и статей на сайтах предлагается записывать в HKEY_CLASSES_ROOT. Если посмотреть в реестре, то да, там все наши ассоциации файлов. Но не привилегированному пользователю туда писать НЕЛЬЗЯ.
Дальше я пошёл на MSDN и вот что там нашёл — msdn.microsoft.com/en-us/library/ms724475.aspx.
Теперь всё стало на свои места. Эта ветка осталась для совместимости со старым софтом. Напрямую писать в неё может только админ. А для всего остального есть 2 другие ветки:
HKEY_LOCAL_MACHINE\Software\Classes — для ассоциаций по-умолчанию
HKEY_CURRENT_USER\Software\Classes — и для пользовательских.
Бинго! Вот он заветный раздел. Сюда мы будем и писать. Кстати для быстрого перехода в эту ветку можно использовать функцию RegOpenUserClassesRoot.
Кажется на этом можно и остановиться, но нет. Мы же не такие.
Вернёмся к HKEY_CLASSES_ROOT. Кто дочитал документацию на MSDN понял, а для остальных поясню как там что-то появляется.
Это очень легко: HKEY_LOCAL_MACHINE\Software\Classes + HKEY_CURRENT_USER\Software\Classes. Вот так. Спросите как тогда админ то может туда записывать? Да просто, он пишет в HKEY_LOCAL_MACHINE\Software\Classes. Но если такой ключ есть в ветке HKEY_CURRENT_USER\Software\Classes, то запишет в неё.
А мораль тут такова: не верь всему, что написано не в официальной документации.
P.S.: Кину сюда кусок класса для работы с файловыми ассоциациями в Delphi 7.
unit RegAsso;
interface
uses
Registry, Classes;
type
TRegAsso = class(TComponent)
private
ext:string;
des:string;
exe:string;
public
procedure Asso;
published
property ExeName : String read exe write exe;
property Description : String read des write des;
property Extension : String read ext write ext;
end;
const HKEY_CURRENT_USER = longWord($80000001);
const CLASSES_PATH = 'Software\Classes\';
implementation
procedure TRegAsso.asso;
var reg:TRegistry;
begin
reg := TRegistry.Create;
reg.RootKey := HKEY_CURRENT_USER;
reg.OpenKey(CLASSES_PATH + ext,true);
reg.WriteString('', des);
reg.CloseKey;
reg.OpenKey(CLASSES_PATH + des,true);
reg.WriteString('',des);
reg.Openkey('DefaultIcon',true);
reg.WriteString('', exe + ', 0');
reg.CloseKey;
reg.OpenKey(CLASSES_PATH + des+'\Shell\Open',true);
reg.WriteString('','&Open');
reg.OpenKey('Command', true);
reg.WriteString('', '"'+ exe+'"' + ' "%1"');
reg.CloseKey;
reg.Free;
end;
end.
Комментарии (9)
RSS свернуть / развернутьunix way на мой взгляд намного удобнее
Sergei_T
durman
Markony
смотря чем заниматься
Sergei_T
forums.kuban.ru/forum/viewtopic_new.php?t=3787627&all=all
yababay
проблемы с реестром это ужас полный — как то раз после обновления рдп клиента не вставали ярлыки .rdp весь мозг себе выпарил — на следующий день каким то макаром все само зашевелилось и начало работать — хз что такое — толи вирь какой толи служба какая мешала — но нет устойчивости и в винде.
FREExLOADER
Sergei_T
с утра до ночи в Linux и не испытываю неудобств))
Sergei_T
yababay
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.