2011-06-12 31 views
0

我在閱讀註冊表時遇到問題。 此函數可查找註冊表路徑中的條目數。它完美的作品,我測試:我無法使用RegOpenKeyEx

void findNumberEntries(registryTest &INSTALLKEY) { 

char buffer[50]; 
char size = sizeof(buffer); 
int index = 0; 

if(RegOpenKeyEx(INSTALLKEY.hKey,(LPTSTR)(INSTALLKEY.regpath.c_str()),0,KEY_ALL_ACCESS,&INSTALLKEY.hKey) == ERROR_SUCCESS) {  

    DWORD readEntry; 

    do { 
     readEntry = RegEnumValue(INSTALLKEY.hKey,index,(LPTSTR)buffer,(LPDWORD)&size,NULL,NULL,NULL,NULL); 
     index++; 
    } 
    while(readEntry != ERROR_NO_MORE_ITEMS); 
} 
INSTALLKEY.number = index; 
RegCloseKey(INSTALLKEY.hKey); 
} 

現在,主要功能:

std::string regpath32 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\"; 
struct registryTest { 
HKEY hKey; 
std::string regpath; 
int number; 
}; 

registryTest INSTALLKEY = {HKEY_LOCAL_MACHINE, regpath32}; 
findNumberEntries(INSTALLKEY); 
printf("%d\n",INSTALLKEY.number); 
system("PAUSE"); 
//until here everything works as it should 

HKEY hKey = INSTALLKEY.hKey; 
std::string regpath = INSTALLKEY.regpath; 
char buffer[50]; 
char size = sizeof(buffer); 
std::string bufferString; 
DWORD regOpen = RegOpenKeyEx(INSTALLKEY.hKey,(LPTSTR)INSTALLKEY.regpath.c_str(),0,KEY_READ,&INSTALLKEY.hKey); 
if(regOpen == ERROR_SUCCESS) //this is the part that fails. 
{ 
    printf("Registry Key was successfully opened\n"); 
} 
else 
{ 
    printf("Unable to open registry key\n"); 
    LPVOID message; 
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
     NULL, GetLastError(), NULL,(LPTSTR) &message, 0, NULL); 
    MessageBox(NULL,(LPCTSTR)message,"ERROR",MB_OK|MB_ICONINFORMATION); 
} 

...rest of the code 

我總是得到「無法打開註冊表」和錯誤消息,我得到的是「沒有更多文件」。問題是什麼??

+1

什麼版本? 32或64位?進程是32位還是64位? – 2011-06-12 15:18:11

+0

它是32位,但在WinXP 32bit,我得到「註冊表項已成功打開」。在Win7 64位我得到這個問題。 – 2011-06-12 15:19:55

+0

但是,我的findNumberEntries()函數即使在Win7 64位上也能正常工作......這很奇怪。 – 2011-06-12 15:25:27

回答

0

您可能還需要在第二個調用中指定KEY_ALL_ACCESS,而不是僅在第一個調用中。在Win7 64位上,您可能會遇到註冊表重定向瘋狂(http://msdn.microsoft.com/zh-cn/library/aa384232%28VS.85%29.aspx)。

編輯:啊,你可能只是得到一個ERROR_CANTWRITE(錯誤代碼5)。你可能會忽略它,看看它是否仍然有效。

0

很可能在Windows 7 64位上,您將通過Registry Virtualization重定向到該位置。您可以通過撥打RegQueryReflectionKey來確定要重定向的密鑰。

如果修改代碼以輸出返回的實際整數值,而不是通用的「無法打開密鑰」,那麼這將有所幫助。例如,

long n = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("\\SOFTWARE"), 
         0,KEY_QUERY_VALUE, &hk); 
    if (n == ERROR_SUCCESS) { 
     cout << "OK" << endl; 
    } 
    else { 
     cout << "Failed with value " << n << endl; 
    } 
+0

我100%確定該鍵被重定向,不需要用RegQueryReflectionKey查找它! – 2011-06-12 15:32:21

+0

@大衛:不傷害檢查:) – 2011-06-12 15:32:52

2

您的問題是,當您第一次打開註冊表項時,您將其分配給您的結構的hkey成員。所以第二次這個hkey不再包含原始的basekey。

變化:

DWORD regOpen = RegOpenKeyEx(INSTALLKEY.hKey,(LPTSTR)INSTALLKEY.regpath.c_str(),0,KEY_READ,& INSTALLKEY.hKey);

DWORD regOpen = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,(LPTSTR)INSTALLKEY.regpath.c_str(),0,KEY_READ,& INSTALLKEY.hKey);

或改變這一點:窗戶的

void findNumberEntries(registryTest &INSTALLKEY) 
{ 
    char buffer[50]; 
    char size = sizeof(buffer); 
    int index = 0; 
    HKEY hkOpen = 0; // can't use INVALID_HANDLE_VALUE for HKEY's; 

    if (RegOpenKeyEx(INSTALLKEY.hKey ,(LPTSTR)(INSTALLKEY.regpath.c_str()) 
        ,0,&hkOpen) == ERROR_SUCCESS) 
    { 
     // You should use RegQueryInfoKey for below code ! 
     DWORD readEntry;  
     do { 
     readEntry = RegEnumValue(hkOpen ,index,(LPTSTR)buffer 
         ,(LPDWORD size,NULL,NULL,NULL,NULL); 
     index++; 
    } 
    while(readEntry != ERROR_NO_MORE_ITEMS); } 
    INSTALLKEY.number = index; 
    RegCloseKey(hkOpen); 
} 
+0

埃德溫這工作完美,非常感謝你。但是hKey並不總是LOCAL_MACHINE,可能是CURRENT_USER,我不知道提前。這就是爲什麼我試圖在我的結構中跟蹤它。我能做什麼?另外,我不明白到底是什麼問題。 – 2011-06-12 17:34:21

+0

問題是您用新打開的密鑰的值覆蓋了hkey成員(最初包含HKEY_LOCAL_MACHINE)。相反,您可以在findNumberEntries(...)中使用本地HKEY變量。 – 2011-06-12 17:42:35

+0

@jack:要獲取有關HKEY的信息,您可以調用RegQueryInfoKey(...),它告訴您有關該密鑰的所有必需信息。 – 2011-06-12 17:50:43