简体   繁体   English

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

[英]Create registry entry to associate file extension with application in C++

I would like to know the cleanest way of registering a file extension with my C++ application so that when a data file associated with my program is double clicked, the application is opened and the filename is passed as a parameter to the application. 我想知道用我的C ++应用程序注册文件扩展名的最简洁方法,以便在双击与我的程序关联的数据文件时,打开应用程序并将文件名作为参数传递给应用程序。

Currently, I do this through my wix installer, but there are some instances where the application will not be installed on ths user's computer, so I also need the option of creating the registry key through the application. 目前,我通过我的wix安装程序执行此操作,但有些情况下应用程序将不会安装在用户的计算机上,因此我还需要通过应用程序创建注册表项的选项。

Additionally, will this also mean that if the application is removed, unused entries in the registry will be left lying around? 此外,这是否也意味着如果删除了应用程序,注册表中未使用的条目将被放置?

Your basic overview of the process is found in this MSDN article . 您可以在此MSDN文章中找到有关该过程的基本概述。 The key parts are at the bottom of the list: 关键部分位于列表的底部:

  • Register the ProgID 注册ProgID

A ProgID (essentially, the file type registry key) is what contains your important file type properties, such as icon, description, and context menu items including application used when the file is double clicked. ProgID(本质上是文件类型注册表项)包含重要的文件类型属性,例如图标,描述和上下文菜单项,包括双击文件时使用的应用程序。 Many extensions may have the same file type. 许多扩展可能具有相同的文件类型。 That mapping is done in the next step: 该映射在下一步中完成:

  • Register the file name extension for the file type 注册文件类型的文件扩展名

Here, you set a registry value for your extension, setting that extension's file type to the ProgID you created in the previous step. 在这里,您为扩展设置了一个注册表值,将该扩展名的文件类型设置为您在上一步中创建的ProgID。

The minimum amount of work required to get a file to open with your application is setting/creating two registry keys. 使用您的应用程序打开文件所需的最少工作量是设置/创建两个注册表项。 In this example .reg file, I create an file type ( blergcorp.blergapp.v1 ) and association a file extension ( .blerg ) with it. 在这个示例.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"

Now, you probably want to accomplish this programmatically. 现在,您可能希望以编程方式完成此操作。 To be absolutely kosher, you could check for the existence of these keys, and change your program behavior accordingly, especially if you're assuming control of some common file extension. 为了绝对犹太,你可以检查这些键的存在,并相应地改变你的程序行为, 特别是如果你正在控制一些常见的文件扩展名。 However, the goal can be accomplished by setting those two keys using the SetValue function. 但是,可以通过使用SetValue函数设置这两个键来实现目标。

I'm not positive of the exact C++ syntax, but in C# the syntax looks something like this: 我不确定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");

Of course you could manually open each sub key, manually create the ProgID and extension subkey, and then set the key value, but a nice thing about the SetValue function is that if the keys or values don't exist, they will automatically be created. 当然你可以手动打开每个子键,手动创建ProgID和扩展子键, 然后设置键值,但SetValue函数的一个SetValue是,如果键或值不存在,它们将自动创建。 Very handy. 非常便利。

Now, a quick word about which hive to use. 现在,快速了解哪个蜂巢使用。 Many file association examples online, including ones on MSDN, show these keys being set in HKEY_CLASSES_ROOT . 许多在线文件关联示例(包括MSDN上的文件关联示例)显示这些键在HKEY_CLASSES_ROOT中设置。 I don't recommend doing this. 我不建议这样做。 That hive is a merged, virtual view of HKEY_LOCAL_MACHINE\\Software\\Classes (the system defaults) and HKEY_CURRENT_USER\\Software\\Classes (the per-user settings), and writes to any subkey in the hive are redirected to the same key in HKEY_LOCAL_MACHINE\\Software\\Classes . 该配置单元是HKEY_LOCAL_MACHINE\\Software\\Classes (系统默认值)和HKEY_CURRENT_USER\\Software\\Classes (每用户设置)的合并虚拟视图,并且对配置单元中的任何子项的写入都将重定向到HKEY_LOCAL_MACHINE\\Software\\Classes的相同键HKEY_LOCAL_MACHINE\\Software\\Classes Now, there's no direct problem doing this, but you may run into this issue: If you write to HKCR (redirected to HKLM), and the user has specified the same keys with different values in HKCU, the HKCU values will take precedence. 现在,这样做没有直接问题,但是您可能会遇到这个问题:如果您写入HKCR(重定向到HKLM),并且用户在HKCU中指定了具有不同值的相同键,则HKCU值将优先。 Therefore, your writes will succeed but you won't see any change, because HKEY_CURRENT_USER settings take precedence over HKEY_LOCAL_MACHINE settings. 因此,您的写入将成功,但您不会看到任何更改,因为HKEY_CURRENT_USER设置优先于HKEY_LOCAL_MACHINE设置。

Therefore, you should take this into consideration when designing your application. 因此,在设计应用程序时应考虑到这一点。 Now, on the flip side you can write to only HKEY_CURRENT_USER , as my examples here show. 现在,另一方面,您只能写入HKEY_CURRENT_USER ,正如我在此处的示例所示。 However, that file association setting will only be loaded for the current user, and if your application has been installed for all users, your application won't launch when that other user opens the file in Windows. 但是,只会为当前用户加载该文件关联设置,如果已为所有用户安装了应用程序,则当其他用户在Windows中打开该文件时,您的应用程序将无法启动。

That should be a decent primer for what you want to do. 对于你想做的事情,这应该是一个不错的入门书。 For further reading I suggest 为了进一步阅读,我建议

And see also my similar answer to a similar question: 另请参阅我对类似问题的类似答案:

This is a two step process: 这是一个两步过程:

1. Define a program that would take care of extension: (unless you want to use existing one)
      1.1 create a key in "HKCU\\Software\\Classes\\" for example 
          "Software\\Classes\\YourProgramName.file.ext"
      1.2 create subkey "Software\\Classes\\YourProgramName.file.ext\\DefaultIcon"
        1.2.1 set default value ("") to your application full path to get
              icon from resources
      1.3 create a subkey "Software\\Classes\\YourProgramName.file.ext\\Shell\\OperationName\\Command"
          OperationName = for example Open, Print or Other
        1.3.1 set default value ("") to your application full path +optional runtime params (filename)

2.Associate file extension with program.
  2.1 create a key HKCU\\Software\\Classes\\.ext   - here goes your extension
  2.2 set default value to the program definition key
    ("YourProgramName.file.ext")

Below is part of the program written in c# which associate file extension. 下面是用c#编写的程序的一部分,它关联文件扩展名。 It is not c++ but i think it is simple enought to explain itself and AFAIK it is verv simmilar if not identical to the code in c++ 它不是c ++,但我认为它很简单,需要解释自己和AFAIK它是verv simmilar如果不是与c ++中的代码相同

1. 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. 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(); 

I don't know why people keep saying that HKEY_CURRENT_USER\\Software\\Classes\\<.ext> 's Default value (which will redirect you into another (software-created) class. 我不知道为什么人们一直说HKEY_CURRENT_USER\\Software\\Classes\\<.ext>的默认值(它会将你重定向到另一个(软件创建的)类。

It does work, but it will be overridden by 它确实有效,但它会被覆盖

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

And I believe Microsoft recommends the second practice- because it's what the built-in "open with" is doing. 而且我相信微软推荐第二种做法 - 因为它是内置的“开放式”所做的。 The value of Progid " key is equal to default value of HKEY_CURRENT_USER\\Software\\Classes\\<.ext> in this case. 在这种情况下, Progid “键的值等于HKEY_CURRENT_USER\\Software\\Classes\\<.ext>默认值。

I found the following while trying to manipulate associations using C#: 我在尝试使用C#操作关联时发现了以下内容:

  • hkcu\\software\\microsoft\\windows\\currentVersion\\explorer\\fileexts.reg\\userchoice -> for user specific settings. hkcu \\ software \\ microsoft \\ windows \\ currentVersion \\ explorer \\ fileexts.reg \\ userchoice - >用于特定于用户的设置。 The values in the openWithProgIds key point to the keys in the hkcr. openWithProgIds键中的值指向hkcr中的键。
  • hkcr\\xfile\\shell\\open\\muiVerb value or hkcr\\xfile\\shell\\open\\command\\default value -> affects open handler. hkcr \\ xfile \\ shell \\ open \\ muiVerb value或hkcr \\ xfile \\ shell \\ open \\ command \\ default value - >影响打开处理程序。 This is the value that contains the path to a program. 这是包含程序路径的值。
  • hkcr\\ .x -> affects context menu (new x) among other things related to the menus. hkcr \\ .x - >影响上下文菜单(新x)以及与菜单相关的其他内容。

I don't know the C++ code, but given these info you must be able to manipulate the registry using the registry API. 我不知道C ++代码,但是根据这些信息,您必须能够使用注册表API来操作注册表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM