我想知道在我的 C++ 应用程序中注册文件扩展名的最简洁方法,以便在双击与我的程序关联的数据文件时,打开应用程序并将文件名作为参数传递给应用程序。
目前,我通过我的 wix 安装程序执行此操作,但在某些情况下应用程序不会安装在用户的计算机上,因此我还需要通过应用程序创建注册表项的选项。
此外,这是否也意味着如果应用程序被删除,注册表中未使用的条目将被遗留下来?
我想知道在我的 C++ 应用程序中注册文件扩展名的最简洁方法,以便在双击与我的程序关联的数据文件时,打开应用程序并将文件名作为参数传递给应用程序。
目前,我通过我的 wix 安装程序执行此操作,但在某些情况下应用程序不会安装在用户的计算机上,因此我还需要通过应用程序创建注册表项的选项。
此外,这是否也意味着如果应用程序被删除,注册表中未使用的条目将被遗留下来?
您可以在此 MSDN 文章中找到对该过程的基本概述。关键部分位于列表的底部:
ProgID(本质上是文件类型注册表项)包含重要的文件类型属性,例如图标、描述和上下文菜单项,包括双击文件时使用的应用程序。许多扩展名可能具有相同的文件类型。该映射在下一步中完成:
在这里,您为扩展设置了一个注册表值,将该扩展的文件类型设置为您在上一步中创建的 ProgID。
使用应用程序打开文件所需的最少工作量是设置/创建两个注册表项。在这个示例.reg文件中,我创建了一个文件类型 ( blergcorp.blergapp.v1) 并将一个文件扩展名 ( .blerg) 与其关联。
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\blergcorp.blergapp.v1\shell\open\command]
@="c:\path\to\app.exe \"%1\""
[HKEY_CURRENT_USER\Software\Classes\.blerg]
@="blergcorp.blergapp.v1"
现在,您可能希望以编程方式完成此操作。为了绝对的犹太教,你可以检查这些键的存在,并相应地改变你的程序行为,特别是如果你假设控制一些常见的文件扩展名。但是,可以通过使用 SetValue 函数设置这两个键来实现目标。
我不赞成确切的 C++ 语法,但在 C# 中,语法看起来像这样:
Registry.SetValue(@"HKEY_CURRENT_USER\Software\Classes\blergcorp.blergapp.v1\shell\open\command", null, @"c:\path\to\app.exe \"%1\"");
Registry.SetValue(@"HKEY_CURRENT_USER\Software\Classes\.blerg", null, "blergcorp.blergapp.v1");
当然你可以手动打开每个子键,手动创建 ProgID 和扩展子键,然后设置键值,但是这个SetValue功能的一个好处是如果键或值不存在,它们会自动创建。非常便利。
现在,简要介绍一下使用哪个蜂巢。许多在线文件关联示例,包括 MSDN 上的示例,都显示这些键设置在HKEY_CLASSES_ROOT. 我不建议这样做。该配置单元是HKEY_LOCAL_MACHINE\Software\Classes(系统默认值)和HKEY_CURRENT_USER\Software\Classes(每个用户设置)的合并虚拟视图,并且对配置单元中的任何子键的写入都被重定向到HKEY_LOCAL_MACHINE\Software\Classes. 现在,这样做没有直接问题,但您可能会遇到这个问题:如果您写入 HKCR(重定向到 HKLM),并且用户在 HKCU 中指定了具有不同值的相同键,则 HKCU 值将优先。因此,您的写入将成功,但您不会看到任何更改,因为HKEY_CURRENT_USER设置优先于HKEY_LOCAL_MACHINE设置。
因此,在设计应用程序时应考虑到这一点。现在,另一方面,您可以只写信给HKEY_CURRENT_USER,正如我在此处的示例所示。但是,该文件关联设置只会为当前用户加载,如果您的应用程序已为所有用户安装,则当其他用户在 Windows 中打开文件时,您的应用程序将不会启动。
对于您想做的事情,这应该是一本不错的入门书。为了进一步阅读,我建议
另请参阅我对类似问题的类似回答:
这是一个两步过程:
1.定义一个程序来处理扩展:(除非你想使用现有的)
1.1 例如在“HKCU\\Software\\Classes\\”中创建一个key
“软件\\类\\你的程序名.file.ext”
1.2 创建子项“Software\\Classes\\YourProgramName.file.ext\\DefaultIcon”
1.2.1 将默认值(“”)设置为您的应用程序完整路径以获取
资源中的图标
1.3 创建子键“Software\\Classes\\YourProgramName.file.ext\\Shell\\OperationName\\Command”
OperationName = 例如打开、打印或其他
1.3.1 将默认值(“”)设置为您的应用程序完整路径+可选运行时参数(文件名)
2.将文件扩展名与程序相关联。
2.1 创建一个密钥 HKCU\\Software\\Classes\\.ext - 这是你的扩展
2.2 给程序定义键设置默认值
(“你的程序名.file.ext”)
下面是用 c# 编写的关联文件扩展名的程序的一部分。它不是 c++,但我认为解释自己和 AFAIK 很简单,如果与 c++ 中的代码不完全相同的话
1.
RegistryKey keyPFCTExt0 = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc", true);
if (keyPFCTExt0 == null)
{
keyPFCTExt0 = Registry.CurrentUser.CreateSubKey("Software\\Classes\\PFCT.file.enc");
keyPFCTExt0.CreateSubKey("DefaultIcon");
RegistryKey keyPFCTExt0ext = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc\\DefaultIcon", true);
keyPFCTExt0ext.SetValue("", Application.ExecutablePath +",0");
keyPFCTExt0ext.Close();
keyPFCTExt0.CreateSubKey("Shell\\PFCT_Decrypt\\Command");
}
keyPFCTExt0.SetValue("", "PFCT.file.enc");
keyPFCTExt0.Close();
2.
RegistryKey keyPFCTExt1 = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc\\Shell\\PFCT_Decrypt\\Command", true);
if (keyPFCTExt1 == null)
keyPFCTExt1 = Registry.CurrentUser.CreateSubKey("Software\\Classes\\PFCT.file.enc\\Shell\\PFCT_Decrypt\\Command");
keyPFCTExt1.SetValue("", Application.ExecutablePath + " !d %1"); //!d %1 are optional params, here !d string and full file path
keyPFCTExt1.Close();
我不知道为什么人们一直说这HKEY_CURRENT_USER\Software\Classes\<.ext>是默认值(这会将您重定向到另一个(软件创建的)类。
它确实有效,但它会被覆盖
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\<.ext>\UserChoice
而且我相信微软推荐第二种做法——因为这是内置的“打开方式”正在做的事情。在这种情况下,Progid" key 的值等于默认值 of 。HKEY_CURRENT_USER\Software\Classes\<.ext>
我在尝试使用 C# 操作关联时发现了以下内容:
我不知道 C++ 代码,但鉴于这些信息,您必须能够使用注册表 API 操作注册表。