C ++ Поиск в реестре Windows - PullRequest
       14

C ++ Поиск в реестре Windows

1 голос
/ 11 октября 2011

Я пытаюсь найти в реестре ключи в определенной группе (Local-> Windows -> Uninstall), чтобы в конечном итоге я мог удалить эти приложения программно.У меня проблемы с получением имени ключа, поэтому я могу его открыть.Вот что я попробовал:

void Uninstall::uninstallProgram(string appName)
{
    HKEY currentKey;
    TCHAR name[1024];
    DWORD dwSize = 1024, dwIdx = 0;
    FILETIME fTime;
    long result;

    result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, POLICY_KEY, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &currentKey);

    if (result != ERROR_SUCCESS)
    {
        cout << "Error opening Installation Registry, verify that this location exists under: " << POLICY_KEY << endl;
        cin.get();
    }
    else
    {
        /*
         * The installation path has been verified, now need to start looking for the correct program to uninstall
         */

        for(int index = 0; result == ERROR_SUCCESS; index++)
        {
            if (RegEnumKeyEx(currentKey, 0, name, &dwSize, NULL, NULL, NULL, &fTime))
            {
                cout << string() << name << endl;
//              if (name == appName)
//              {
//                  system(execute the uninstall string)
//              }
            }
        }


    }

Как я могу получить имя текущего ключа, чтобы сравнить его с именем приложения, которое я пытаюсь удалить?Спасибо.

Ответы [ 5 ]

1 голос
/ 11 октября 2011

Похоже, вы просто забыли запросить у KEY_ENUMERATE_SUB_KEYS права доступа. Также возможно, что я не совсем понимаю, что вы пытаетесь сделать, но папка AFAIK Uninstall находится в другом месте.

HKEY currentKey;
TCHAR name[1024];
DWORD dwSize = 1024, dwIdx = 0;
long result;
result = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall" ), 0, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_SET_VALUE, &currentKey);

if (result != ERROR_SUCCESS)
{
  // fail
}
else
{
  DWORD index = 0;
  while ( ERROR_SUCCESS == RegEnumKeyEx(currentKey, index, name, &dwSize, NULL, NULL, NULL, NULL) ) {
    // name buffer is already contains key name here
    // ...
    dwSize = 1024; // restore dwSize after is is set to key's length by RegEnumKeyEx
    ++index; // increment subkey index
  } 
}
0 голосов
/ 25 июня 2016

ниже - рабочий скомпилированный код для рекурсивного поиска в реестре имени значения, я знаю, что многие ищут его, и я думаю, что нет никакого рабочего кода для этого.

скомпилировано с использованием MinGW

// Say Shaloom to Ammar Hourani who did code troubleshooting and compiled this
// QueryKey - Enumerates the subkeys of key and its associated values.
//     hKey - Key whose subkeys and values are to be enumerated.

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <iostream.h>
#include <wchar.h>
#include <string.h>



#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383


void QueryKey(char * originalpath , char * searchvalue) 
{ 

    HKEY hKey;
    if( RegOpenKeyEx( HKEY_CURRENT_USER,TEXT(originalpath),0,KEY_READ,&hKey)     == ERROR_SUCCESS)
       {
           TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
            DWORD    cbName;                   // size of name string 
            TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
            DWORD    cchClassName = MAX_PATH;  // size of class string 
            DWORD    cSubKeys=0;               // number of subkeys 
            DWORD    cbMaxSubKey;              // longest subkey size 
            DWORD    cchMaxClass;              // longest class string 
            DWORD    cValues;              // number of values for key 
            DWORD    cchMaxValue;          // longest value name 
            DWORD    cbMaxValueData;       // longest value data 
            DWORD    cbSecurityDescriptor; // size of security descriptor 
            FILETIME ftLastWriteTime;      // last write time 

            DWORD i, retCode; 

            CHAR  achValue[MAX_VALUE_NAME]; 

            DWORD cchValue = MAX_VALUE_NAME; 
            char * dndr = new char[MAX_VALUE_NAME]();


            // Get the class name and the value count. 
            retCode = RegQueryInfoKey(
                hKey,                    // key handle 
                achClass,                // buffer for class name 
                &cchClassName,           // size of class string 
                NULL,                    // reserved 
                &cSubKeys,               // number of subkeys 
                &cbMaxSubKey,            // longest subkey size 
                &cchMaxClass,            // longest class string 
                &cValues,                // number of values for this key 
                &cchMaxValue,            // longest value name 
                &cbMaxValueData,         // longest value data 
                &cbSecurityDescriptor,   // security descriptor 
                &ftLastWriteTime);       // last write time 

            // Enumerate the subkeys, until RegEnumKeyEx fails.
        if (cSubKeys)
        {


            for (i=0; i<cSubKeys; i++) 
            { 
                cbName = MAX_KEY_LENGTH;
                retCode = RegEnumKeyEx(hKey,     i,achKey,&cbName,NULL,NULL,NULL,&ftLastWriteTime); 
                if (retCode == ERROR_SUCCESS) 
                {
                    strcpy(dndr,originalpath);

                    strcat(dndr,"\\");
                    strcat(dndr,achKey);

                    QueryKey(dndr,searchvalue);

                }
            }
        } 

        // Enumerate the key values. 

        if (cValues) 
        {


            for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) 
            { 
                cchValue = MAX_VALUE_NAME; 
                //achValue[0] = '\0'; 
                memset(achValue, 0, sizeof(achValue));
                retCode = RegEnumValue(hKey, i, 
                achValue, 
                &cchValue, 
                NULL, 
                NULL,
                NULL,
                NULL);

            if (retCode == ERROR_SUCCESS ) 
            {
                if (!strncmp(achValue,searchvalue,strlen(searchvalue))) cout << "\n One Hit at: " << originalpath << endl;

            } 
        }
    }
}
RegCloseKey(hKey);
}


int __cdecl _tmain(void)
{
   QueryKey("Software\\Microsoft\\Office","MTTA");
   cin.get();
   return 1;

}
0 голосов
/ 11 октября 2011

Вы должны использовать текущий индекс, чтобы получить имя, а затем проверить на ERROR_NO_MORE_ITEMS:

bool quit = false;

for(int index = 0; !quit; index++)
{
    LSTATUS Return = RegEnumKeyEx(currentKey, index, name, &dwSize, NULL, NULL, NULL, &fTime);
    if(Return == ERROR_NO_MORE_ITEMS)
    {
        quit = true;
    }
    else if(Return == ERROR_SUCCESS)
    {
        cout << string() << name << endl;
    }
    else
    {
        quit = true;
    }
}
0 голосов
/ 11 октября 2011

Вам необходимо включить вашу индексную переменную в ваш вызов RegEnumKeyEx. Вы всегда передаете 0 для параметра dwIndex. Прекратите перечисление, когда оно возвращает ERROR_NO_MORE_ITEMS.

0 голосов
/ 11 октября 2011

Необработанный API для доступа к реестру довольно уродлив - стандартная практика - использовать один из многих доступных классов-оболочек, которые делают это в целом менее болезненным. В кодпроекте их буквально десятки.

...