如何为我的应用程序取消注册文件格式? [英] How to unregister a File Format for my application?
问题描述
在 Windows 10 的 Delphi 10.4.2 win-32 VCL 应用程序中,我使用
然而,当我尝试使用 DSiWin32.DSiUnregisterUserFileAssoc
为我的图形应用程序取消注册 .ICO
文件格式时,它不起作用:
procedure TForm1.btnUnregisterClick(Sender: TObject);开始DSiUnregisterUserFileAssoc('UGAICOFile');SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);结尾;
UGAICOFile
progID 键没有从注册表中删除!在文件资源管理器中双击 .ICO 文件仍会加载我的应用程序!
即使我在提升模式下尝试(以管理员身份启动程序),它也不起作用!会不会是.ico\OpenWithProgrids
下注册的微软应用程序可以阻止密钥被删除?
那么我如何为我的应用程序取消注册已注册的 .ICO
文件格式?
问题似乎是 DSiUnregisterUserFileAssoc
函数没有获得所需的注册表访问级别.
我在编程时的一个经验法则是,除非绝对必要,否则永远不要使用第三方库,部分原因是您不了解它们的所有细节.在这种情况下,我不太明白添加一个相当大的库只是为了做一些简单的注册表更改的意义!
手动建立关联 很简单:
var Reg := TRegistry.Create;尝试Reg.RootKey := HKEY_CURRENT_USER;如果 Reg.OpenKey('\Software\Classes\.myfile', True) 然后Reg.WriteString('', 'MyAppDataFile');如果 Reg.OpenKey('\Software\Classes\MyAppDataFile', True) 然后Reg.WriteString('', '我自己的文本文件类型');如果 Reg.OpenKey('\Software\Classes\MyAppDataFile\DefaultIcon', True) 然后Reg.WriteString('', 'C:\WINDOWS\notepad.exe');如果 Reg.OpenKey('\Software\Classes\MyAppDataFile\shell\open\command', True) 然后Reg.WriteString('', 'C:\WINDOWS\notepad.exe "%1"');最后注册免费;结尾;SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
删除它也是如此:
var Reg := TRegistry.Create;尝试Reg.RootKey := HKEY_CURRENT_USER;Reg.DeleteKey('\Software\Classes\MyAppDataFile');最后注册免费;结尾;SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
这是有效的,它不需要额外的库(有很多你不需要的东西,潜在的安全问题,潜在的错误等),而且你确切地知道代码的作用.您已 100% 了解它.
通过将其更改为以下内容,我能够使 DSi 功能正常工作:
DSiKillRegistry('\Software\Classes\' + progID, HKEY_CURRENT_USER, KEY_ALL_ACCESS);
In a Delphi 10.4.2 win-32 VCL Application in Windows 10, I register the .ICO
file format for my graphics application by using DSiWin32.DSiRegisterUserFileAssoc:
DSiRegisterUserFileAssoc(
'.ico', // extension: .ico
'UGAICOFile', // progID: UGAICOFile
'ICO File', // description: ICO File
'C:\DELPHI\MyApp\MyApp.ico', // Icon File
'"C:\DELPHI\MyApp\Win32\Debug\MyApp.exe" "%1"' // openCommand
);
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
This works without problems and when double-clicking an .ICO file in Windows File Explorer my app loads the .ICO file. These Registry keys have been created WITH THE CORRECT VALUES:
HOWEVER, when I try to UNREGISTER the .ICO
file format for my graphics application by using DSiWin32.DSiUnregisterUserFileAssoc
, it does not work:
procedure TForm1.btnUnregisterClick(Sender: TObject);
begin
DSiUnregisterUserFileAssoc('UGAICOFile');
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;
The UGAICOFile
progID key is not being deleted from the Registry! And double-clicking an .ICO file in File Explorer still loads my app!
Even when I try it in elevated mode (by starting the program as Administrator) it does not work! Could it be that that the Microsoft apps registered under .ico\OpenWithProgrids
could stop the key from being removed?
So how can I UNREGISTER the registered .ICO
File Format for my application?
The problem seems to be the DSiUnregisterUserFileAssoc
function not obtaining the required access level to the registry.
One of my rules of thumb when programming is to never use third-party libraries unless absolutely necessary, partly because you don't know all the details about them. And in this case, I don't quite see the point in adding a fairly large library just to do a few simple registry changes!
Making an association manually is trivial:
var Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CURRENT_USER;
if Reg.OpenKey('\Software\Classes\.myfile', True) then
Reg.WriteString('', 'MyAppDataFile');
if Reg.OpenKey('\Software\Classes\MyAppDataFile', True) then
Reg.WriteString('', 'My Very Own Text File Type');
if Reg.OpenKey('\Software\Classes\MyAppDataFile\DefaultIcon', True) then
Reg.WriteString('', 'C:\WINDOWS\notepad.exe');
if Reg.OpenKey('\Software\Classes\MyAppDataFile\shell\open\command', True) then
Reg.WriteString('', 'C:\WINDOWS\notepad.exe "%1"');
finally
Reg.Free;
end;
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
And so is removing it:
var Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CURRENT_USER;
Reg.DeleteKey('\Software\Classes\MyAppDataFile');
finally
Reg.Free;
end;
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
This works, it requires no additional library (with a lot of things you don't need, potential security issues, potential bugs, etc.), and you know exactly what the code does. You have 100% understanding of it.
I was able to make the DSi function work by changing it to this:
DSiKillRegistry('\Software\Classes\' + progID, HKEY_CURRENT_USER, KEY_ALL_ACCESS);
这篇关于如何为我的应用程序取消注册文件格式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!