如何为我的应用程序取消注册文件格式? [英] How to unregister a File Format for my application?

查看:78
本文介绍了如何为我的应用程序取消注册文件格式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆