创buildregistry项以将文件扩展名与C ++中的应用程序相关联

我想知道使用C ++应用程序注册文件扩展名的最简单的方法,这样当双击与我的程序关联的数据文件时,应用程序就会打开,文件名作为parameter passing给应用程序。

目前,我通过我的wix安装程序来执行此操作,但是有些情况下应用程序不会安装在用户的计算机上,所以我还需要通过应用程序创buildregistry项。

此外,这是否也意味着如果应用程序被删除,registry中的未使用的项目将被留下?

您在这个MSDN文章中find您的过程的基本概述。 关键部分在列表的底部:

  • 注册ProgID

一个ProgID(本质上,文件typesregistry项)是什么包含您的重要文件types属性,如图标,说明和上下文菜单项,包括双击文件时使用的应用程序。 许多扩展可能具有相同的文件types。 该映射在下一步中完成:

  • 注册文件types的文件扩展名

在这里,为您的扩展设置registry值,将该扩展的文件types设置为您在上一步中创build的ProgID。

使用应用程序打开文件所需的最less工作量是设置/创build两个registry项。 在这个例子.reg文件中,我创build了一个文件types( 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"); 

当然你可以手动打开每个子键,手动创buildProgID和扩展子键, 然后设置键值,但是关于SetValue函数的SetValue在于,如果键或值不存在,它们将自动创build。 非常方便。

现在,简单介绍一下哪个蜂巢可以使用。 在线的许多文件关联示例(包括MSDN上的文件关联示例)都显示了在HKEY_CLASSES_ROOT中设置的这些键。 我不build议这样做。 该configuration单元是HKEY_LOCAL_MACHINE\Software\Classes (系统默认值)和HKEY_CURRENT_USER\Software\Classes (每个用户的设置)的合并虚拟视图,并且写入configuration单元中的任何子项都被redirect到HKEY_LOCAL_MACHINE\Software\Classes 。 现在,这样做没有直接的问题,但是你可能遇到这个问题:如果你写信给HKCR(redirect到HKLM),并且用户在HKCU中指定了不同值的相同的密钥,那么HKCU值将优先。 因此,您的写入将会成功,但您不会看到任何更改,因为HKEY_CURRENT_USER设置优先于HKEY_LOCAL_MACHINE设置。

因此,在devise应用程序时应考虑到这一点。 现在,另一方面,你可以只写入HKEY_CURRENT_USER ,就像我这里的示例所示。 但是,只会为当前用户加载该文件关联设置,并且如果已经为所有用户安装了应用程序,则当其他用户在Windows中打开文件时,您的应用程序将不会启动。

这应该是你想要做的一个体面的底漆。 为了进一步阅读,我build议

  • 文件关联的最佳实践
  • 文件types和文件关联 ,特别是
  • 文件关联如何工作

另请参阅我对类似问题的类似回答:

  • 将文件扩展名与程序相关联

这是一个两步过程:

  1.定义一个可以处理扩展的程序(除非你想使用现有的程序)
      例如,在“HKCU \\ Software \\ Classes \\”中创build一个密钥 
           “SOFTWARE \\ \\类YourProgramName.file.ext”
       1.2创build子项“Software \\ Classes \\ YourProgramName.file.ext \\ DefaultIcon”
         1.2.1设置默认值(“”)到你的应用程序的完整path来获取
              资源图标
       1.3创build一个子项“Software \\ Classes \\ YourProgramName.file.ext \\ Shell \\ OperationName \\ Command”
           OperationName =例如打开,打印或其他
         1.3.1设置默认值(“”)到你的应用程序的完整path+可选的运行时参数(文件名)

 2.与程序分离文件扩展名。
   2.1创build一个密钥HKCU \ Software \\ Classes \\。ext  - 这里是你的扩展
   2.2将默认值设置为程序定义键
     ( “YourProgramName.file.ext”)

下面是用C#编写的程序的一部分,它关联文件扩展名。 这不是C ++,但我认为这是很简单的足以解释自己和AFAIK它是verv simmilar,如果不是相同的代码在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();
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();
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>的默认值(这会将您redirect到另一个(软件创build的)类。

它确实有效,但会被覆盖

 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\<.ext>\UserChoice 

而且我相信微软推荐的第二种做法是因为这是内置的“打开”function。 Progid “键的值等于默认值HKEY_CURRENT_USER\Software\Classes\<.ext>在这种情况下。