2009-10-03 46 views
1

什麼代碼添加到這個函數工作好? (ERROR_SUCCESS)RegQueryValueEx - 這個函數添加了什麼代碼來顯示ERROR_SUCCESS

我有代碼,檢查註冊表中的值。

功能RegQueryValueEx是bug。 當oldValue是幾個字母比newValue更長,功能顯示ERROR_MORE_DATA,但我想要想ERROR_SUCCESS

什麼代碼添加到這個功能做到這一點?

void function(string newValue, string key, string name) 

{ 

// string key - key in registry, ie Myapp\\Options 
// string name - name in registry 
// string newValue - data in REG_SZ 


string oldValue; 
DWORD keytype = REG_SZ; 
    HKEY keyHandle; 
DWORD size = sizeof(string); 
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(),0L,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS) 
{ 


    LONG isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE)&oldValue, &size); 
    if(isgood == ERROR_MORE_DATA) 
    { 
    cout << "Error more data\n"; 
    } 
    if(isgood == ERROR_SUCCESS) 
    { 
    cout << "Old data is " << oldValue.c_str() << endl; 
    cout << "New data is " << newValue.c_str() << endl; 
    if(strcmp(newValue.c_str(), oldValue.c_str()) != 0) // compare 2 strings, if 
    { 
    cout << "String 1 and string 2 are different"; 

    } 
    else 
    { 
    cout << "String 1 and string 2 are the same"; 
    } 
    } 
    if(isgood == ERROR_FILE_NOT_FOUND) 
    { 
    cout << "Name in registry not found!"; 
    } 
} 

} 

回答

2

ERROR_MORE_DATA表示您需要傳入較大的字符串緩衝區。您需要使用的典型模式是調用一次獲取大小,然後分配適當大小的緩衝區,然後再次調用。或者,也可以猜測大小,傳入大小緩衝區,並在返回ERROR_MORE_DATA時增加大小。

順便說一句,你也計算錯誤的大小。而且你沒有關閉註冊表項。而且您不準備支持在unicode或非unicode模式下進行編譯。

下面是一些修改後的代碼,它們解決了這些問題。

#include <string> 
#include <vector> 
#include <iostream> 

#include <windows.h> 
using namespace std; 

namespace std 
{ 
#ifdef _UNICODE 
    #define tcout wcout 
    #define tcin wcin 
    typedef wstring tstring; 
#else 
    #define tcout cout 
    #define tcin cin 
    typedef string tstring; 
#endif 
}; 

void function(tstring newValue, tstring key, tstring name) 
{ 
    // string key - key in registry, ie Myapp\\Options 
    // string name - name in registry 
    // string newValue - data in REG_SZ 
    HKEY keyHandle; 
    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(),0L,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS) 
    { 
     DWORD size = 500; // initial size 
     vector<TCHAR> buf(size); 
     tstring oldValue; 
     DWORD keytype = REG_SZ; 

     LONG isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE) &buf[0], &size); 
     if(isgood == ERROR_SUCCESS) 
     { 
      oldValue.assign (&buf[0], size); 
     } 
     else if(isgood == ERROR_MORE_DATA) 
     { 
      buf.reserve (size); // expand to however large we need 
      isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE)&buf[0], &size); 
      if(isgood == ERROR_SUCCESS) 
       oldValue.assign (&buf[0], size); 
     } 
     RegCloseKey (keyHandle); // remember to close this! 
     if(isgood == ERROR_SUCCESS) 
     { 
      tcout << _T("Old data is ") << oldValue << endl; 
      tcout << _T("New data is ") << newValue << endl; 
      if(newValue.compare(oldValue) != 0) // compare 2 strings, if 
      { 
       tcout << _T("String 1 and string 2 are different"); 

      } 
      else 
      { 
       tcout << _T("String 1 and string 2 are the same"); 
      } 
     } 
     if(isgood == ERROR_FILE_NOT_FOUND) 
     { 
      tcout << _T("Name in registry not found!"); 
     } 
    } 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    tstring val; 
    function (val, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"), _T("CommonFilesDir")); 
    return 0; 
} 
+0

謝謝賈斯汀·格蘭特爲完整的代碼,我現在知道我做錯了:* – Jasmin25 2009-10-04 01:44:39

+0

但當我添加到註冊表數據「foo」和運行此程序用新的數據「富」它表明: 舊數據foo 新數據爲foo 字符串1和字符串2不同 但foo和foo的值相同。 如何更改此代碼以使其運行良好? – Jasmin25 2009-10-04 02:09:20

+0

不確定。也許其中一個字符串包含空終止符字符,而其中一個字符串沒有,導致長度不同?在任何情況下,請逐字逐個查看字符串,然後找出它們的不同之處以及如何解決問題。 – 2009-10-04 02:35:33

2

ERROR_MORE_DATA表示您提供的用於保存數據的緩衝區不夠大。

你的問題是多方面的:

  1. 當你說的sizeof(串),你得到的字符串數據類型,而不是字符串的長度的大小。你應該調用string :: size()來獲取字符串的長度。
  2. 您不能只將一個字符串投射到LPBYTE。悲慘的是,這將失敗。註冊表API不適用於string s,它們被設計爲與char*WCHAR*類型一起使用。您需要聲明本地字符數組(例如char *foo = new char[256]),然後通過該數組。如果你得到ERROR_MORE_DATA,則申報一個更大的。