IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Utilisation de RegQueryValueEx.


Sujet :

C++

  1. #1
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut Utilisation de RegQueryValueEx.
    Hello,

    Je débute en c++ et je me heurte à un problème d'affichage.

    Sur le principe, j'essayes de faire une fonction "GetDataKeyString" qui me renvoie une donnée de valeur de clé de registre en string.

    En base de Registre, j'ai ceci :
    Key : HKEY_CURRENT_USER\SOFTWARE\0000
    Value : "Essai"
    Data : 'Donnée de la valeur essai"


    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    // main.cpp
     
    #include <windows.h>
    #include <string>
     
    using namespace std;
     
    string GetDataKeyString(HKEY rootKey, wstring regSubKey, wstring regValueKey)
    {
    /*
    LONG WINAPI RegCreateKeyEx(
      _In_        HKEY hKey,
      _In_        LPCTSTR lpSubKey,
      _Reserved_  DWORD Reserved,
      _In_opt_    LPTSTR lpClass,
      _In_        DWORD dwOptions,
      _In_        REGSAM samDesired,
      _In_opt_    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
      _Out_       PHKEY phkResult,
      _Out_opt_   LPDWORD lpdwDisposition
    );
     
    LONG RegQueryValueEx( 
      HKEY hKey, 
      LPCWSTR lpValueName, 
      LPDWORD lpReserved, 
      LPDWORD lpType, 
      LPBYTE lpData, 
      LPDWORD lpcbData 
    ); 
    */
     
     
      LONG lResult;
      TCHAR regDataKey[MAX_PATH];
      DWORD regDataKeyLength = sizeof(regDataKey);
     
     
      //Creation du handle
        HKEY hKey;
        if (RegOpenKeyEx( 
    	                  rootKey, 
    	                  regSubKey.c_str(), 
    	                  0, 
    		       KEY_ALL_ACCESS, 
                          	       &hKey) == ERROR_SUCCESS)
     
       {
    	    cout << "Key found" << endl;
     
             //Contrôle
            //_tprintf( TEXT("\ RegOpenKeyEx  OPENED"));
     
    		lResult = RegQueryValueEx(
    			            hKey, 
    				regValueKey.c_str(),
    				NULL, 
    				NULL, 
                                                 (LPBYTE)&regDataKey, 
                                                 &regDataKeyLength); 
     
    		if (lResult == ERROR_SUCCESS)
     
    		{
     
    		       cout << "Value found" << endl;
      	                  //_tprintf(TEXT("Data : %s\n"), regDataKey);
     
                                 std::string s( reinterpret_cast<char const*>(regDataKey), regDataKeyLength) ;
    	    return s;
     
     
    		}
    		else
    		{
    		    cout << "Value not found" << endl;
    		}   
     
            RegCloseKey( hKey);
        }	
    	else
    	{
    	   cout << "Key not found" << endl;
    	}
     
    }	  
     
    int main()
    {
     
    	string s;
    	s = GetDataKeyString(HKEY_CURRENT_USER,L"SOFTWARE\\0000\\", L"Essai");
    	cout << "String Data : " + s << endl;
    	system("PAUSE");
     
     
       return 0;
    }
    Ma donnée comporte la chaîne de caractères 'Donnée de la valeur essai"

    Cela fonctionne sans erreur de compilation, mais l'affichage de la donnée se fait curieusement avec un espace entre chaque caractère.

    Le résultat est celui-ci :
    D o n n é e d e l a v a l e u r e s s a i

    Merci d'avance si vous pouvez m'aider.

    A bientôt...

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Utilise une wstring pour les données aussi.

    Enfin pour être pédant, il faudrait que tu utilises des basic_string<TCHAR> à la place, mais bon on n'est plus à cela près.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut
    Hello Médinoc,

    J'ai essayé la solution, mais cela ne fonctionne pas, j'ai une erreur de compilation car le retour n'est pas un string

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      std:basic_string<TCHAR> str = regDataKey;
                cout << str << endl;   // ---> seul le wcout est accepté
                return str;     // ---> ce n'est pas un string
    Merci quand même.

    A+

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ah en effet, tu devrais te faire un tcout aussi à base de #define.

    En fait, c'est simple: Soit tu bosses entièrement en TCHAR, soit tu privilégies les wchar_t. Et là où il faut, tu convertis (MultiByteToWideChar(), WideCharToMultiByte() etc.).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    std::string GetRegistryValue(HKEY hkRegistry, const char* szValue)
    {
    	DWORD   dwType;
    	DWORD   dwSize ;
     
    	LONG lRegResult = RegQueryValueEx(hkRegistry, szValue, NULL, &dwType, NULL, &dwSize);
    	if (lRegResult!=ERROR_SUCCESS) return "";
    	char* buffer = new char[dwSize];
            std::string strResult;
     
    	lRegResult = RegQueryValueEx(hkRegistry, szValue, NULL, &dwType, (LPBYTE)buffer, &dwSize);
    	if (lRegResult==ERROR_SUCCESS)
    	strResult = buffer;
     
    	delete[] buffer;
    	return strResult;
    }
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ce code ne marche que s'il est compilé en mode non-Unicode.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut
    Hello,

    Je n'ai pas réussi à le faire fonctionné avec vos suggestions. Alors je suis revenu à ma fonction d'origine.

    Je me suis finalement rendu compte que le code affiché prenait en charge le caractère zéro terminal. Il m'a suffit tout simplement de supprimer toutes les occurences de la chaîne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #include <algorithm>
    s.erase( std::remove( s.begin(), s.end(), '\0' ), s.end() );
    Voici mon code final qui fonctionne parfaitement maintenant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    // main.cpp
    // Nicolas Coolman 16/12/2013
    
    #include <windows.h>
    #include <string>
    #include <algorithm>
     
    using namespace std;
     
    string GetDataKeyString(HKEY rootKey, wstring regSubKey, wstring regValueKey)
    {
    /*
    
    LONG WINAPI RegOpenKeyEx(
      _In_        HKEY hKey,
      _In_opt_    LPCTSTR lpSubKey,
      _Reserved_  DWORD ulOptions,
      _In_        REGSAM samDesired,
      _Out_       PHKEY phkResult
    );
     
    LONG RegQueryValueEx( 
      HKEY hKey, 
      LPCWSTR lpValueName, 
      LPDWORD lpReserved, 
      LPDWORD lpType, 
      LPBYTE lpData, 
      LPDWORD lpcbData 
    ); 
    */
     
      LONG lResult;
      TCHAR regDataKey[MAX_PATH];
      DWORD regDataKeyLength = sizeof(regDataKey);
     
     
      //Creation du handle
        HKEY hKey;
        if (RegOpenKeyEx( 
    	                  rootKey, 
    	                  regSubKey.c_str(), 
    	                  0, 
     		    KEY_ALL_ACCESS, 
                          	    &hKey
                                    ) == ERROR_SUCCESS)
     
       {
             cout << "Key found" << endl;
     
             //Contrôle
            //_tprintf( TEXT("\ RegOpenKeyEx  OPENED"));
     
    		lResult = RegQueryValueEx(
    			            hKey, 
    				regValueKey.c_str(),
    				NULL, 
    				NULL, 
                                                 (LPBYTE)&regDataKey, 
                                                 &regDataKeyLength); 
     
    		if (lResult == ERROR_SUCCESS)
     
    		{
     
    		       cout << "Value found" << endl;
                                   
                                     //Contrôle
      	                  //_tprintf(TEXT("Data : %s\n"), regDataKey);
     
                                   std::string s( reinterpret_cast<char const*>(regDataKey), regDataKeyLength) ;
                      	   s.erase( std::remove( s.begin(), s.end(), '\0' ), s.end() ); 
    	                 return s;
    
    		}
    		else
    		{
    		    cout << "Value not found" << endl;
    		}   
     
            RegCloseKey( hKey);
        }	
    	else
    	{
    	   cout << "Key not found" << endl;
    	}
     
    }	  
    
    int main()
    {
     
    	string s;
    	s = GetDataKeyString(HKEY_CURRENT_USER,L"SOFTWARE\\0000\\", L"Essai");
    	cout << "Data found : " + s << endl;
    	system("PAUSE");
     
     
       return 0;
    }
    Merci à vous tous pour vos idées et remarques.

    A bientôt...

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ça ne marchera pas pour les caractères non-latins... ou le symbole Euro.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut
    Hello Medinoc,

    En fait je répondrais oui et non !

    Oui, tu as parfaitement raison car de tels caractères ne seront pas pris en compte avec la fonction "Cout", au même titre d'ailleurs que les caractères accentués.

    Non, car si tu places le résultat de la fonction dans un fichier texte, les caractères spéciaux seront biens pris en compte. (passage par std::ofstream file)

    En fait, mon abjectif final est de pouvoir placer des informations dans un fichier de rapport (texte) comme c'est déjà le cas avec mon logiciel ZHPDiag si tu en as connaissance (Ecrit en Delphi).


    A+

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Non, je peux t'assurer que retirer les octets nuls d'un texte en UTF-16 fera foirer tous les caractères qui ne sont pas Latin-1.

    Dont le symbole Euro, dont le code est U+20AC (il apparaîtra donc en tant que "¬ " vu que les caractères larges de Windows sont en little-endian)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut
    Re,

    Pourtant mes tests sont OK, si tu veux tu peux tester aussi en suivant cette procédure :


    1) Créer un fichier vide "C:\essai.txt"

    2) Modifier le code précédant en ajoutant cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void ajouteUneLigneRapport(string uneLigne)
        string const monFichier = "C:/essai.txt";
        ofstream monFlux(monFichier);
     
       std::ifstream fichier(monFichier)  
       {
       std::ofstream file( monFichier, std::ios_base::app );
        file << uneLigne;
        }
    }
    3) Modifier le main comme cela, :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main()
    {
     
                 string s;
    	s = GetDataKeyString(HKEY_CURRENT_USER,L"SOFTWARE\\0000\\", L"Essai");
    	ajouteUneLigneRapport(s);
     
       return 0;
    }
    4) saisir dans le registre :

    Key : HKEY_CURRENT_USER\SOFTWARE\0000
    Value : "Essai"
    Data : 'Donnée de la valeur essai €€€€€€"
    5) Lancer le programme,

    Le résultat donne la ligne suivante dans "C:\essai.txt"
    Donnée de la valeur essai €€€€€€
    A+

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    J'ai recopié exactement ton code dans mon Visual Studio 2008, n'ajoutant que ce qui manquait pour que ça compile:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    // main.cpp
    // Nicolas Coolman 16/12/2013
     
    #include <windows.h>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <algorithm>
     
    using namespace std;
     
    string GetDataKeyString(HKEY rootKey, wstring regSubKey, wstring regValueKey)
    {
    /*
     
    LONG WINAPI RegOpenKeyEx(
      _In_        HKEY hKey,
      _In_opt_    LPCTSTR lpSubKey,
      _Reserved_  DWORD ulOptions,
      _In_        REGSAM samDesired,
      _Out_       PHKEY phkResult
    );
     
    LONG RegQueryValueEx( 
      HKEY hKey, 
      LPCWSTR lpValueName, 
      LPDWORD lpReserved, 
      LPDWORD lpType, 
      LPBYTE lpData, 
      LPDWORD lpcbData 
    ); 
    */
     
      LONG lResult;
      TCHAR regDataKey[MAX_PATH];
      DWORD regDataKeyLength = sizeof(regDataKey);
     
     
      //Creation du handle
        HKEY hKey;
        if (RegOpenKeyEx( 
    	                  rootKey, 
    	                  regSubKey.c_str(), 
    	                  0, 
     		    KEY_ALL_ACCESS, 
                          	    &hKey
                                    ) == ERROR_SUCCESS)
     
       {
             cout << "Key found" << endl;
     
             //Contrôle
            //_tprintf( TEXT("\ RegOpenKeyEx  OPENED"));
     
    		lResult = RegQueryValueEx(
    			            hKey, 
    				regValueKey.c_str(),
    				NULL, 
    				NULL, 
                                                 (LPBYTE)&regDataKey, 
                                                 &regDataKeyLength); 
     
    		if (lResult == ERROR_SUCCESS)
     
    		{
     
    		       cout << "Value found" << endl;
     
                                     //Contrôle
      	                  //_tprintf(TEXT("Data : %s\n"), regDataKey);
     
                                   std::string s( reinterpret_cast<char const*>(regDataKey), regDataKeyLength) ;
                      	   s.erase( std::remove( s.begin(), s.end(), '\0' ), s.end() ); 
    	                 return s;
     
    		}
    		else
    		{
    		    cout << "Value not found" << endl;
    		}   
     
            RegCloseKey( hKey);
        }	
    	else
    	{
    	   cout << "Key not found" << endl;
    	}
     
    }	  
     
    void ajouteUneLigneRapport(string uneLigne)
    {
        string const monFichier = "C:/temp/essai.txt";
        ofstream monFlux(monFichier.c_str());
     
       std::ifstream fichier(monFichier.c_str());
       {
       std::ofstream file( monFichier.c_str(), std::ios_base::app );
        file << uneLigne;
        }
    }
     
    extern"C" void TestStringWeirdness()
    {
     
    	string s;
    	s = GetDataKeyString(HKEY_CURRENT_USER,L"SOFTWARE\\0000\\", L"Essai");
    	cout << "Data found : " + s << endl;
    	ajouteUneLigneRapport(s);
    	system("PAUSE");
     
     
       //return 0;
    }
    Dans l'éditeur du Registre, j'ai créé la valeur chaîne:
    Test 5€ test €€€€€
    Et j'ai obtenu dans essai.txt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Test 5¬  test ¬ ¬ ¬ ¬ ¬
    comme je l'avais annoncé.

    PS: En cas de succès, ta fonction GetDataKeyString() retourne sans appeler RegCloseKey().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut
    Re,

    Il s'agit peut-être d'une question d'O.S. ?

    Je développe sous :
    Visual C++ 2010 Express.
    Windows 7 Professional, 64-bit Service Pack 1 (Build 7601)

    Tu as quoi comme système d'exploitation ?

    A+

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Visual C++ 2008 Express,
    Windows Vista Ultimate 32 bits
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut
    Hello,

    Je me demande si le plus simple ne serait pas que tu proposes un code source qui fonctionne sur ta station afin que je puisses tester le résultat.

    A bientôt...

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ce code récupère la clé en TCHAR, puis la convertit en Windows-1252 avant de l'afficher et l'écrire dans le fichier.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    #include <Windows.h>
    #include <string>
    #include <fstream>
    #include <iostream>
    #include <vector>
    using namespace std;
     
    namespace std {
    	typedef basic_string<TCHAR> _tstring;
    }
     
    //Class for closing a registry key
    class CHKey
    {
    	HKEY hKey;
    public:
    	CHKey() : hKey() {}
    	explicit CHKey(HKEY hKey) : hKey(hKey) {}
    	CHKey(HKEY hParentKey, LPCSTR subKey,  REGSAM access) : hKey() { RegOpenKeyExA(hParentKey, subKey, 0, access, &this->hKey); }
    	CHKey(HKEY hParentKey, LPCWSTR subKey, REGSAM access) : hKey() { RegOpenKeyExW(hParentKey, subKey, 0, access, &this->hKey); }
    	CHKey(CHKey && src) : hKey(hKey) { src.hKey=NULL; }
    	~CHKey() { RegCloseKey(hKey); }
    	operator HKEY() const { return hKey; }
    private:
    	CHKey(CHKey const &); //Visual Studio 2010 doesn't know of "=delete"
    	CHKey& operator=(CHKey const &);
    };
     
    //String conversion functions
    string GetStringA(string s) { return s; }
    string GetStringA(wstring s, int codePage=CP_ACP)
    {
    	int cbBufSize = WideCharToMultiByte(codePage, 0, s.c_str(), -1, NULL, 0, NULL, NULL);
    	vector<char> buf(cbBufSize);
    	WideCharToMultiByte(codePage, 0, s.c_str(), -1, &buf[0], cbBufSize, NULL, NULL);
    	string ret(&buf[0]);
    	return ret;
    }
    wstring GetStringW(string s, int codePage=CP_ACP)
    {
    	int cchBufSize = MultiByteToWideChar(codePage, 0, s.c_str(), -1, NULL, 0);
    	vector<wchar_t> buf(cchBufSize);
    	MultiByteToWideChar(codePage, 0, s.c_str(), -1, &buf[0], cchBufSize);
    	wstring ret(&buf[0]);
    	return ret;
    }
    wstring GetStringW(wstring s) { return s; }
    //String conversion functions with a code page ID
    string GetStringA(string s, int codePage) { return GetStringA(GetStringW(s), codePage); }
    wstring GetStringW(wstring s, int codePage) { (void)codePage; return s; }
     
    //Registry functions
    _tstring GetRegValueString(HKEY hKey, _tstring valueName)
    {
    	DWORD type = REG_NONE;
    	DWORD cb = 0;
    	LSTATUS status = RegQueryValueEx(hKey, valueName.c_str(), NULL, &type, NULL, &cb);
    	if(status != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
    		return TEXT(""); //Should probably throw an exception instead.
     
    	//Round the byte size UP to a character size, and add a null character just to be sure
    	size_t cch = (cb + sizeof(TCHAR)-1) / sizeof(TCHAR) + 1;
     
    	vector<TCHAR> buf(cch);
    	status = RegQueryValueEx(hKey, valueName.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&buf[0]), &cb);
    	if(status != ERROR_SUCCESS)
    		return TEXT(""); //Should probably throw an exception instead.
     
    	_tstring ret(&buf[0]);
    	return ret;
    }
     
    _tstring GetRegValueString(HKEY hKey, _tstring subKey, _tstring valueName)
    {
    	CHKey shSubKey(hKey, subKey.c_str(), KEY_READ);
    	return GetRegValueString(shSubKey, valueName);
    }
     
    void ajouteUneLigneRapport(string uneLigne)
    {
    	string const monFichier = "C:/temp/essai.txt";
    	std::ofstream file( monFichier.c_str(), std::ios_base::app );
    	file << uneLigne << endl;
    }
     
    int main(void)
    {
    	_tstring s = GetRegValueString(HKEY_CURRENT_USER, TEXT("SOFTWARE\\0000\\"), TEXT("Essai"));
    	string s2 = GetStringA(s);
    	cout << "Data found (converted to extended ASCII) : " + s2 << endl;
    	ajouteUneLigneRapport(s2);
    	return 0;
    }
    Tu peux même modifier facilement le code pour l'avoir en UTF-8 à la place.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut
    Hello,

    J'ai crée un nouveau projet et recopié intégralement ton code pour le tester :

    J'ai d'office une erreur de compilation à la ligne 69, le & de &buf[0] est en faute :
    _tstring ret(&buf[0]);


    ------ Début de la génération*: Projet*: Tests, Configuration*: Debug Win32 ------
    1> Main.cpp
    1>g:\langagec\projets\tests\tests\main.cpp(69): error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,_Ax> &)'*: impossible de convertir le paramètre 1 de 'wchar_t *' en 'const std::basic_string<_Elem,_Traits,_Ax> &'
    1> with
    1> [
    1> _Elem=char,
    1> _Traits=std::char_traits<char>,
    1> _Ax=std::allocator<char>
    1> ]
    1> Raison*: impossible de convertir de 'wchar_t *' en 'const std::basic_string<_Elem,_Traits,_Ax>'
    1> with
    1> [
    1> _Elem=char,
    1> _Traits=std::char_traits<char>,
    1> _Ax=std::allocator<char>
    1> ]
    1> Aucun constructeur n'a pu prendre le type de source, ou la résolution de la surcharge du constructeur était ambiguë
    ========== Génération*: 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========
    A+

  18. #18
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    En effet, j'ai confondu wchar_t et TCHAR.
    Code corrigé:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    _tstring GetRegValueString(HKEY hKey, _tstring valueName)
    {
    	DWORD type = REG_NONE;
    	DWORD cb = 0;
    	LSTATUS status = RegQueryValueEx(hKey, valueName.c_str(), NULL, &type, NULL, &cb);
    	if(status != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
    		return TEXT(""); //Should probably throw an exception instead.
     
    	//Round the byte size UP to a character size, and add a null character just to be sure
    	size_t cch = (cb + sizeof(TCHAR)-1) / sizeof(TCHAR) + 1;
     
    	vector<TCHAR> buf(cch);
    	status = RegQueryValueEx(hKey, valueName.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&buf[0]), &cb);
    	if(status != ERROR_SUCCESS)
    		return TEXT(""); //Should probably throw an exception instead.
     
    	_tstring ret(&buf[0]);
    	return ret;
    }
    NOTE: Le message d'erreur montre que tu compilais en non-unicode. RegGetValueEx() dans ton code n'aurait même pas dû accepter de compiler avec une wstring...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Membre régulier Avatar de Nicolas Coolman
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 76
    Points
    76
    Par défaut
    Hello,

    Bravo ! cela fonctionne parfaitement !

    A bientôt...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 16h57
  2. Réponses: 4
    Dernier message: 05/06/2002, 15h35
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 13h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 17h01
  5. Réponses: 2
    Dernier message: 21/03/2002, 00h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo