Créer une entrée de Registre pour associer une extension de fichier à une application en C++

j'aimerais connaître la façon la plus propre d'enregistrer une extension de fichier avec mon application C++ de sorte que lorsqu'un fichier de données associé à mon programme est cliqué deux fois, l'application est ouverte et le nom du fichier est passé comme paramètre à l'application.

actuellement, je le fais par l'intermédiaire de mon installateur wix, mais il y a des cas où l'application ne sera pas installée sur l'ordinateur de l'utilisateur ths, donc j'ai également besoin de l'option de créer la clé de registre par le biais de l'application.

de plus, cela signifie-t-il également que si la demande est retirée, les entrées inutilisées dans le registre seront laissées en suspens?

40
demandé sur Seth 2009-09-07 10:07:50

3 réponses

votre aperçu de base du processus se trouve dans cet article de MSDN . Les éléments clés sont en bas de la liste:

  • Enregistrer le prog.

un Prog (essentiellement, la clé de registre de type de fichier) est ce qui contient vos propriétés de type de fichier importantes, telles que les éléments de menu icône, description, et contexte, y compris l'application utilisée lorsque le fichier est double cliqué. De nombreuses extensions peuvent avoir le même type de fichier. Cette cartographie est réalisée à l'étape suivante:

  • enregistrer l'extension de nom de fichier pour le type de fichier

ici, vous définissez une valeur de Registre pour votre extension, en définissant le type de fichier de cette extension au programme que vous avez créé à l'étape précédente.

le minimum de travail requis pour obtenir un fichier à ouvrir avec votre application est de définir/créer deux clés de registre. Dans cet exemple .reg fichier, je crée un type de fichier ( blergcorp.blergapp.v1 ) et associe une extension de fichier ( .blerg ) avec elle.

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"

maintenant, vous voulez probablement accomplir cette programmatically. Pour être absolument casher, vous pourriez vérifier l'existence de ces clés, et changer votre comportement de programme en conséquence, surtout si vous assumez le contrôle d'une certaine extension de fichier commune. Toutefois, l'objectif peut être atteint en établissant ces deux touches utilisant la fonction SetValue.

Je ne suis pas sûr de la syntaxe exacte de C++, mais en C# la syntaxe ressemble à quelque chose comme ceci:

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");

bien sûr, vous pouvez ouvrir manuellement chaque sous-clé, créer manuellement la sous-clé de programme et d'extension, et puis définir la valeur de la clé, mais une chose agréable à propos de la fonction SetValue est que si les clés ou les valeurs n'existent pas, elles seront automatiquement créées. Très pratique.

maintenant, un mot rapide sur la ruche à utiliser. De nombreux exemples d'association de fichiers en ligne, y compris ceux sur MSDN, montrent ces clés étant définies dans HKEY_CLASSES_ROOT . Je ne recommande pas de faire cela. Cette Ruche est une vue virtuelle fusionnée de HKEY_LOCAL_MACHINE\Software\Classes (le système par défaut) et HKEY_CURRENT_USER\Software\Classes (les paramètres par utilisateur), et les Écritures à n'importe quel sous-clé dans la ruche sont redirigées vers la même clé dans HKEY_LOCAL_MACHINE\Software\Classes . Maintenant, il n'y a aucun problème à faire cela, mais vous pouvez rencontrer ce genre de problème: Si vous Ecrire à HKCR (redirigé vers HKLM), et l'Utilisateur a spécifié les mêmes clés avec des valeurs différentes dans HKCU, les valeurs HKCU auront priorité. Par conséquent, vos Écritures réussiront mais vous ne verrez aucun changement, parce que les paramètres HKEY_CURRENT_USER ont priorité sur les paramètres HKEY_LOCAL_MACHINE .

par conséquent, vous devez en tenir compte lors de la conception de votre application. Maintenant, de l'autre côté, vous pouvez écrire à seulement HKEY_CURRENT_USER , comme mes exemples ici montrent. Cependant, ce paramètre d'association de fichier ne sera chargé que pour l'utilisateur courant, et si votre application a été installée pour tous les utilisateurs, votre application ne se lancera pas lorsque cet autre utilisateur ouvrira le fichier sous Windows.

ça devrait être une bonne base pour ce que vous voulez faire. Pour plus de lecture je suggère

Et voir aussi mon semblable réponse à une question similaire:

71
répondu Factor Mystic 2017-05-23 11:54:56

il s'agit d'un processus en deux étapes:

 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")

ci-dessous fait partie du programme écrit en c# qui associe l'extension de fichier. Il n'est pas c++ mais je pense qu'il est simple de s'expliquer et AFAIK il est Verv simmilar sinon identique au code en 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(); 

7
répondu beermann 2009-09-09 21:52:16

Je ne sais pas pourquoi les gens disent que la valeur par défaut de HKEY_CURRENT_USER\Software\Classes\<.ext> (qui vous redirigera dans une autre classe (créée par logiciel).

ça marche, mais il sera dépassé par

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

et je crois que Microsoft recommande la deuxième pratique - parce que c'est ce que fait" open with " intégré. La valeur de Progid " clé est égale à la valeur par défaut de HKEY_CURRENT_USER\Software\Classes\<.ext> dans ce cas.

6
répondu fireattack 2016-06-10 08:33:25