簡體   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