CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - pobranie listy lub tabeli KeyValue z klucza rejestru

pobranie listy lub tabeli KeyValue z klucza rejestru

dział ogólny

pobranie listy lub tabeli KeyValue z klucza rejestru

Nowy postprzez Android » niedziela, 13 lutego 2011, 00:22

Witam,
Chciałbym uzyskać z rejestru spis przechowywanych wartości - ich nazwy.
Na przykład załóżmy, że aplikacja przechowuje w rejestrze informacje takie jak wymiar i położenie okna. Dane są zapisywane w HKEY_CURRENT_USER w kluczu Software\NazwProducenta\NazwaAplikacji\. Mają nazwy odpowiednio Height, Width, Top, Left.
Sytuacja jaka mnie interesuje ma miejsce wtedy gdy nie znamy nazw (Height, Width, Top, Left) ani ilosci wpisów. Chciałbym pobrać np. tablice z nazwami lub liste - w każdym bądź razie coś co pozwoli sprawdzić ile jest i jakie nazwy mają wpisy oraz dzięki temu później odwołać się do tych wpisów - najlepiej w pętli.
Z góry dziękuję za pomoc.
Avatar użytkownika
Android
Bladawiec
Bladawiec
 
Posty: 46
Dołączył(a): poniedziałek, 5 kwietnia 2010, 16:51
Podziękował : 16
Otrzymał podziękowań: 2
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: pobranie listy lub tabeli KeyValue z klucza rejestru

Nowy postprzez polymorphism » niedziela, 13 lutego 2011, 10:45

Do dokumentacji nie łaska zajrzeć? -> TRegistry::GetValueNames.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: pobranie listy lub tabeli KeyValue z klucza rejestru

Nowy postprzez Cyfrowy Baron » niedziela, 13 lutego 2011, 12:44

Chodzi oczywiście o pobranie nazw wartości. Mając nazwy wartości w kluczu można już bez problemu pobrać przypisane im dane. Do pobrania nazw wartości z klucza służy oczywiście funkcja GetValueName. Pobranie wartości klucza zależy już w dużej mierze od jego typu. Proponuję taki kod:

KOD cpp:     UKRYJ  
#include <registry.hpp>
#include <memory>

void __fastcall ReadKeyValues(HKEY hKey, String subKey, TListView *ListView)
{
  TRegistry *Rejestr = new TRegistry();
  Rejestr->RootKey = hKey; /* otwieram drzewo */

  /* otwieram klucz, false - nie tworzę jeżeli klucz nie istnieje */
  if( !Rejestr->OpenKey(subKey, false) )
  {
   ShowMessage("Nieprawidłowy klucz!");
   delete Rejestr;
   return;
  }

  std::auto_ptr<TStrings> vList(new TStringList);

  Rejestr->GetValueNames(vList.get());

  ListView->Items->Clear();

  int x = -1;
  while(vList->Count - 1 > x++)
  {
   String ValueName = vList->Strings[x];

   TRegDataType rDT = Rejestr->GetDataType(ValueName);

   String DataType  = "";
   String DataValue = Rejestr->GetDataAsString(ValueName, false);

   switch(rDT)
   {
    case rdUnknown:
    {
     DataType = "REG_MULTI_SZ";
     TCHAR lpByte[8192];
     DWORD lpcbData = 8192;
     HKEY hqKey;
     if(RegOpenKeyEx( hKey, subKey.c_str(), 0,
                   KEY_QUERY_VALUE, &hqKey)  == ERROR_SUCCESS)
     {

      if( RegQueryValueEx( hqKey, ValueName.c_str(), NULL, NULL,
                         (LPBYTE)lpByte, &lpcbData) == ERROR_SUCCESS)
      {
       DataValue = lpByte;
      }

      RegCloseKey(hqKey);
     }
     break;
    }
    case rdString:       DataType = "REG_SZ"; break;
    case rdBinary:       DataType = "REG_BINARY"; break;
    case rdInteger:
    {
     DataType = "REG_DWORD";
     int iVal = DataValue.ToIntDef(0);
     DataValue = StringReplace(Rejestr->GetDataAsString(ValueName, true),
                 "dword:", "0x", TReplaceFlags() << rfReplaceAll)
                 + " (" + (String)iVal + ")";
     break;
    }
    case rdExpandString: DataType = "REG_EXPAND_SZ"; break;
   }

   TListItem * ElementListy = ListView->Items->Add();
   ElementListy->Caption = ValueName;
   ElementListy->SubItems->Add(DataType);
   ElementListy->SubItems->Add(DataValue);
  }

  delete Rejestr;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 ReadKeyValues( HKEY_LOCAL_MACHINE,
                "HARDWARE\\DESCRIPTION\\System",
                ListView1 );
}


Wynik zapisywany jest w obiekcie typu TListView, gdyż doskonale się do tego celu nadaje. Kod nie jest jednak w pełni funkcjonalny, gdyż wartości typu REG_MULTI_SZ i REG_EXPAND_SZ powinny być pobierane do jakiejś struktury, ale nie bardzo wiem do jakiej, a w pomocy nic konkretnego na ten temat nie ma. Poza tym rozróżnianie typów kluczy też pozostawia wiele do życzenia, gdyż w przykładzie TRegDataType będąca metodą klasy TRegistry nie rozróżnia typów REG_MULTI_SZ i REG_FULL_RESOURCE_DESCRIPTOR.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Android
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: pobranie listy lub tabeli KeyValue z klucza rejestru

Nowy postprzez Android » niedziela, 13 lutego 2011, 20:26

Bardzo dziękuję za pomoc :)
Avatar użytkownika
Android
Bladawiec
Bladawiec
 
Posty: 46
Dołączył(a): poniedziałek, 5 kwietnia 2010, 16:51
Podziękował : 16
Otrzymał podziękowań: 2
System operacyjny: Windows 7 Pro x64
Kompilator: C++ Builder XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: pobranie listy lub tabeli KeyValue z klucza rejestru

Nowy postprzez Cyfrowy Baron » poniedziałek, 14 lutego 2011, 10:03

Po namyśle prezentuję poprawiony sposób odczytywania wartości typu REG_MULTI_SZ, tak by funkcja ReadKeyValues pobierała całą zawartość tego typu:

KOD cpp:     UKRYJ  
void __fastcall ReadKeyValues(HKEY hKey, String subKey, TListView *ListView)
{
  TRegistry *Rejestr = new TRegistry();
  Rejestr->RootKey = hKey;

  if( !Rejestr->OpenKey(subKey, false) )
  {
   ShowMessage("Nieprawidłowy klucz!");
   delete Rejestr;
   return;
  }

  std::auto_ptr<TStrings> vList(new TStringList);

  Rejestr->GetValueNames(vList.get());

  ListView->Items->Clear();

  int x = -1;
  while(vList->Count - 1 > x++)
  {
   String ValueName = vList->Strings[x];

   TRegDataType rDT = Rejestr->GetDataType(ValueName);

   String DataType  = "";
   String DataValue = Rejestr->GetDataAsString(ValueName, false);

   switch(rDT)
   {
    case rdUnknown:
    {
     DataType = "REG_MULTI_SZ";
     TCHAR lpByte[8192] = {'\0'};
     DWORD lpcbData = 8192;
     DWORD lpType;
     HKEY hqKey;
     if(RegOpenKeyEx( hKey, subKey.c_str(), 0,
                   KEY_QUERY_VALUE, &hqKey)  == ERROR_SUCCESS)
     {

      if( RegQueryValueEx( hqKey, ValueName.c_str(), NULL, &lpType,
                         (LPBYTE)lpByte, &lpcbData) == ERROR_SUCCESS)
      {
       if(lpType == REG_MULTI_SZ)
       {
        int y = 0;
        while(lpcbData > y++)
        {
         if(lpByte[y] == '\0') lpByte[y] = ' '; /* lpByte[y] = '\r' - dla zachowania układu listy */
        }
        DataValue = Trim((String)lpByte);
       }

       switch(lpType)
       {
        case 9:  DataType = "REG_QWORD"; break;
        case 10: DataType = "REG_QWORD_LITTLE_ENDIAN"; break;
       }
      }

      RegCloseKey(hqKey);
     }
     break;
    }
    case rdString:       DataType = "REG_SZ"; break;
    case rdBinary:       DataType = "REG_BINARY"; break;
    case rdInteger:
    {
     DataType = "REG_DWORD";
     int iVal = DataValue.ToIntDef(0);
     DataValue = StringReplace(Rejestr->GetDataAsString(ValueName, true),
                 "dword:", "0x", TReplaceFlags() << rfReplaceAll)
                 + " (" + (String)iVal + ")";
     break;
    }
    case rdExpandString: DataType = "REG_EXPAND_SZ"; break;
   }

   TListItem * ElementListy = ListView->Items->Add();
   ElementListy->Caption = ValueName;
   ElementListy->SubItems->Add(DataType);
   ElementListy->SubItems->Add(DataValue);
  }

  delete Rejestr;
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 43 gości

cron