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

J’aimerais connaître la méthode la plus propre pour enregistrer une extension de fichier avec mon application C ++. Ainsi, lorsqu’un double-clic est associé à un fichier de données, l’application est ouverte et le nom de fichier transmis en tant que paramètre à l’application.

Actuellement, je le fais via mon programme d’installation wix, mais il y a des cas où l’application ne sera pas installée sur l’ordinateur de cet utilisateur, aussi j’ai besoin de la possibilité de créer la clé de registre via l’application.

En outre, cela signifie-t-il également que si l’application est supprimée, les entrées inutilisées dans le registre seront laissées en suspens?

Votre aperçu de base du processus se trouve dans cet article MSDN . Les parties clés sont au bas de la liste:

  • Enregistrez le ProgID

Un ProgID (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 d’icône, de description et de menu contextuel, y compris l’application utilisée lorsque le fichier est double-cliqué. De nombreuses extensions peuvent avoir le même type de fichier. Ce mappage se fait à 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 sur le ProgID que vous avez créé à l’étape précédente.

La quantité minimale de travail requirejse pour qu’un fichier s’ouvre avec votre application consiste à définir / créer deux clés de registre. Dans cet exemple de fichier .reg , je crée un type de fichier ( blergcorp.blergapp.v1 ) et associe une extension de fichier ( .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" 

Maintenant, vous voulez probablement accomplir cela par programmation. Pour être absolument casher, vous pouvez vérifier l’existence de ces clés et modifier le comportement de votre programme en conséquence, surtout si vous assumez le contrôle d’une extension de fichier commune. Cependant, l’objective peut être atteint en définissant ces deux clés à l’aide de la fonction SetValue.

Je ne suis pas sûr de la syntaxe C ++ exacte, mais en C # la syntaxe ressemble à 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 le sous-clé ProgID et l’extension, puis définir la valeur de la clé, mais la fonction SetValue l’ SetValue créer automatiquement les clés ou les valeurs. . Très utile.

Maintenant, un petit mot sur la hive à utiliser. De nombreux exemples d’association de fichiers en ligne, y compris ceux sur MSDN, montrent que ces clés sont définies dans HKEY_CLASSES_ROOT . Je ne recommande pas de le faire. Cette hive est une vue virtuelle fusionnée de HKEY_LOCAL_MACHINE\Software\Classes (les valeurs par défaut du système) et HKEY_CURRENT_USER\Software\Classes (parameters par utilisateur). Les écritures sur n’importe quelle sous-clé du répertoire sont redirigées vers la même clé dans HKEY_LOCAL_MACHINE\Software\Classes . Maintenant, il n’y a pas de problème direct, mais vous pouvez rencontrer ce problème: Si vous écrivez sur HKCR (redirigé vers HKLM) et que 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 aucune modification, car les parameters HKEY_CURRENT_USER ont priorité sur les parameters HKEY_LOCAL_MACHINE .

Par conséquent, vous devez en tenir compte lors de la conception de votre application. En revanche, vous ne pouvez écrire que HKEY_CURRENT_USER , comme le montrent mes exemples ici. Cependant, ce paramètre d’association de fichiers ne sera chargé que pour l’utilisateur actuel 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.

Cela devrait être une bonne introduction à ce que vous voulez faire. Pour plus de lecture je suggère

  • Meilleures pratiques pour l’association de fichiers
  • Types de fichiers et association de fichiers , en particulier
  • Comment fonctionnent les associations de fichiers

Et voir aussi ma réponse similaire à une question similaire:

  • Association d’extensions de fichiers à un programme

Ceci est un processus en deux étapes:

  1. Définissez un programme qui prendrait en charge l’extension: (sauf si vous souhaitez en utiliser un existant)
       1.1 créer une clé dans "HKCU \\ Software \\ Classes \\" par exemple 
           "Software \\ Classes \\ YourProgramName.file.ext"
       1.2 créer une sous-clé "Software \\ Classes \\ YourProgramName.file.ext \\ DefaultIcon"
         1.2.1 définir la valeur par défaut ("") sur le chemin d'access complet de votre application pour obtenir
               icône des ressources
       1.3 créer une sous-clé "Software \\ Classes \\ YourProgramName.file.ext \\ Shell \\ OperationName \\ Commande"
           OperationName = par exemple Open, Print ou Other
         1.3.1 définir la valeur par défaut ("") sur le chemin d'access complet de votre application + les parameters d'exécution optionnels (nom de fichier)

 2.Associer une extension de fichier au programme.
   2.1 créer une clé HKCU \\ Software \\ Classes \\. Ext - voici votre extension
   2.2 définir la valeur par défaut sur la clé de définition du programme
     ("YourProgramName.file.ext")

Vous trouverez ci-dessous une partie du programme écrit en c # qui associe une extension de fichier. Ce n’est pas c ++ mais je pense que c’est assez simple pour s’expliquer et AFAIK c’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();
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 ssortingng 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 ssortingng and full file path keyPFCTExt1.Close(); 

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

Cela fonctionne, mais il sera remplacé par

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

Et je crois que Microsoft recommande la deuxième pratique – car c’est ce que fait le “open with” intégré. La valeur de Progid “key est égale à la valeur par défaut de HKEY_CURRENT_USER\Software\Classes\<.ext> dans ce cas.