C ++搜索Windows注册表

时间:2011-10-10 20:46:18

标签: c++ windows registry key

我正在尝试在注册表中搜索特定组中的密钥(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 个答案:

答案 0 :(得分:1)

您似乎忘记了请求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
  } 
}

答案 1 :(得分:0)

用于注册表访问的原始api非常难看 - 它的标准做法是使用许多可用的包装类中的一个,这使得整体不那么痛苦。在codeproject上有几十个这样的。

答案 2 :(得分:0)

您必须使用当前索引获取名称,然后检查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;
    }
}

答案 3 :(得分:0)

您需要在RegEnumKeyEx调用中包含索引变量。您总是在0中输入dwIndex参数。停止枚举何时返回ERROR_NO_MORE_ITEMS。

答案 4 :(得分:0)

下面是一个工作的编译代码,以递归方式在注册表中搜索值名称,我知道很多人正在寻找它,我认为没有可用的代码来执行此操作。

使用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;

}