C++ 搜索 Windows 注册表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7718471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 18:15:10  来源:igfitidea点击:

C++ Search Windows Registry

c++windowsregistrykey

提问by tier1

I'm trying to search the registry for keys in a particular group(Local-> Windows -> Uninstall) so I can eventually uninstall these applications programatically. I am having problems getting the key name so I can open it. Here is what I have tried:

我正在尝试在注册表中搜索特定组中的键(本地-> Windows -> 卸载),以便我最终可以以编程方式卸载这些应用程序。我在获取密钥名称时遇到问题,因此我无法打开它。这是我尝试过的:

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)
//              }
            }
        }


    }

How can I retrieve the current key name to compare it against the name of the application that I am trying to uninstall? Thanks.

如何检索当前密钥名称以将其与我尝试卸载的应用程序名称进行比较?谢谢。

采纳答案by Ilya Denisov

It seems that you just forgot to request KEY_ENUMERATE_SUB_KEYS access right. Also it's possible that I do not understand exactly what are you trying to do but AFAIK Uninstall folder have different location.

看来您只是忘记请求 KEY_ENUMERATE_SUB_KEYS 访问权限。也有可能我不明白你到底想做什么,但 AFAIK 卸载文件夹有不同的位置。

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
  } 
}

回答by Ammar Hourani

below is a working compiled code to recursively search through registry for a value name , i know lotta people are looking for it and i think there is no working code around to do this .

下面是一个有效的编译代码,用于通过注册表递归搜索值名称,我知道很多人正在寻找它,我认为没有可用的代码来做到这一点。

compiled using MinGW

使用 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] = '
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;
    }
}
'; 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; }

回答by Ricibob

The raw api for registry access is pretty ugly - its standard practice to use one of the many available wrapper classes that make this a whole less painful. There are literally dozens of these on codeproject.

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

回答by pezcode

You have to use the current index to get the name, and then check for ERROR_NO_MORE_ITEMS:

您必须使用当前索引来获取名称,然后检查ERROR_NO_MORE_ITEMS

##代码##

回答by Jim Rhodes

You need to include your index variable in your RegEnumKeyEx call. You are always passing in 0 for the dwIndex parameter. Stop enumerating when it returns ERROR_NO_MORE_ITEMS.

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