创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>在这种情况下。