web-dev-qa-db-fra.com

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

Je voudrais connaître la manière la plus simple d'enregistrer une extension de fichier avec mon application C++ afin que lorsqu'un fichier de données associé à mon programme est double-cliqué, l'application soit ouverte et le nom de fichier soit transmis en paramètre à l'application.

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

De plus, cela signifie-t-il également que si l'application est supprimée, les entrées inutilisées du registre resteront en suspens?

41
Seth

Votre aperçu de base du processus se trouve dans cet article MSDN . Les éléments 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 l'icône, la description et les éléments du 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 est effectué à 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 requise pour ouvrir un fichier avec votre application consiste à 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 associer une extension de fichier (.blerg) avec ça.

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 programme. Pour être absolument casher, vous pouvez vérifier l'existence de ces clés et modifier le comportement de votre programme en conséquence, en particulier si vous assumez le contrôle de certaines extension de fichier. Cependant, l'objectif 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 ProgID et la sous-clé d'extension, et puis définir la valeur de la clé, mais une bonne chose à propos du SetValue La fonction est que si les clés ou les valeurs n'existent pas, elles seront automatiquement créées. Très utile.

Maintenant, un petit mot sur la ruche à 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 faire ça. Cette ruche 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 (les paramètres par utilisateur) et les écritures sur n'importe quelle sous-clé de la ruche sont redirigées vers la même clé dans HKEY_LOCAL_MACHINE\Software\Classes. Maintenant, il n'y a pas de problème direct à faire cela, mais vous pouvez rencontrer ce problème: si vous écrivez dans 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 aucun changement, car HKEY_CURRENT_USER les paramètres ont priorité sur HKEY_LOCAL_MACHINE paramètres.

Par conséquent, vous devez en tenir compte lors de la conception de votre application. Maintenant, d'un autre côté, vous ne pouvez écrire que sur 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 dans Windows.

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

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

76
Factor Mystic

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

 1. Définissez un programme qui prendrait en charge l'extension: (sauf si vous souhaitez en utiliser un déjà existant) 
 1.1 créez une clé dans "HKCU \\ Software \\ Classes \\" par exemple 
 "Software \\ Classes \\ YourProgramName.file.ext" 
 1.2 créer la sous-clé "Software \\ Classes \\ YourProgramName.file.ext \\ DefaultIcon" 
 1.2.1 set valeur par défaut ("") du chemin d'accès complet de votre application pour obtenir l'icône 
 des ressources 
 1.3 créer une sous-clé "Software \\ Classes \\ YourProgramName.file.ext \\ Shell \\ OperationName \\ Commande "
 OperationName = par exemple Ouvrir, Imprimer ou Autre 
 1.3.1 définir la valeur par défaut (" ") sur le chemin d'accès complet de votre application + paramètres d'exécution facultatifs (nom de fichier) 
 
 2.Associer l'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 à la clé de définition de programme 
 ("YourProgramName.file.ext") 
 

Ci-dessous fait partie du programme écrit en c # qui associe l'extension de fichier. Ce n'est pas du 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();

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
beermann

Je ne sais pas pourquoi les gens continuent à dire que la valeur par défaut de HKEY_CURRENT_USER\Software\Classes\<.ext> (Qui vous redirigera 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 la clé Progid "est égale à la valeur par défaut de HKEY_CURRENT_USER\Software\Classes\<.ext> Dans ce cas.

6
fireattack

J'ai trouvé ce qui suit en essayant de manipuler des associations à l'aide de C #:

  • hkcu\software\Microsoft\windows\currentVersion\Explorer\fileexts.reg\userchoice -> pour les paramètres spécifiques à l'utilisateur. Les valeurs de la clé openWithProgIds pointent vers les clés du hkcr.
  • la valeur hkcr\xfile\Shell\open\muiVerb ou hkcr\xfile\Shell\open\command\default value -> affecte le gestionnaire ouvert. Il s'agit de la valeur qui contient le chemin d'accès à un programme.
  • hkcr\.x -> affecte le menu contextuel (nouveau x) entre autres choses liées aux menus.

Je ne connais pas le code C++, mais étant donné ces informations, vous devez être en mesure de manipuler le registre à l'aide de l'API de registre.

0
Meghdad