繁体   English   中英

C ++搜索Windows注册表

[英]C++ Search Windows Registry

我正在尝试在注册表中搜索特定组(本地-> 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)
//              }
            }
        }


    }

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

看来您只是忘记了请求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
  } 
}

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

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

}

用于注册表访问的原始api很丑陋-使用许多可用包装类之一的标准做法,这使整个过程不那么痛苦。 在代码项目中,实际上有数十种。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM