2010-08-05 95 views
0

所以我一直停留在這一段時間......還以爲我得到它的工作,但它有時會中斷,我不知道確切的原因...C++讀取和寫入註冊表正確

我不知道這是否重要,但我正在編寫這個內部瀏覽器幫助對象(BHO)...是否IE總是32位進程,無論它是否在64和32位操作系統上運行?

,所以我希望能夠從註冊表中讀取,我可能需要箱子的關鍵...

我用這個函數:

if (RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\\ProductName", 0, NULL, 
        REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | KEY_WOW64_32KEY, 
        NULL, &hk, NULL) == ERROR_SUCCESS) 

然後我檢查是否有鍵存在這樣的:

TCHAR ext_id[20]; 
DWORD toolbarIdLength; 

if(RegQueryValueEx(hk, L"ext_id", NULL, NULL, 
        (LPBYTE)ext_id, &extIdLength) == ERROR_SUCCESS) 

如果成功,那麼我確定它是空終止:

ext_id[extIdLength] = 0; 

否則我使用WININET LIB的信息發送到我的服務器,分配新EXT_ID和我寫註冊表這個值...使用此功能:

RegSetValueEx(hk, L"ext_id", 0, REG_SZ, (const BYTE *)ext_id, _tcslen(ext_id)*2 + 1); 

因爲它是隻寫一半的一些奇怪的原因我傳遞的東西,所以我加倍_tcslen(ext_id)並添加1安全?大部分時間我發現網上沒有該長度乘以2的例子,它爲我這個樣子,所以我離開它獨自...

似乎這一切工作正常:

和它的工作對我dev_machine :Windows 7 64bit。

測試了32位Windows 7 ...

問題一起在Windows XP的IE 6來了,也沒有工作,但似乎如果我再打電話函數RegQueryValueEx,它會返回正確的值,所以我注意到下一個請求...

我還注意到,根據我發送到服務器的其他字符串,它會工作不同,這可能是由於我相對較新的C++ ,(只有幾個星期真的在),我確信我正在做一些真正錯誤的事情。

呵呵我在msdn上讀到我需要在打開註冊表項的標誌中使用KEY_WOW64_32KEY或KEY_WOW64_64KEY,這取決於情況......但這對我來說確實非常必要(瀏覽器6.0到8.0的BHO)

回答

0

你已經失去了Windows處理unicode的方式。 Dev Studio有一個方便的開關,可以讓您在應用程序的Unicode和Multibyte版本之間切換,並且您正在爲Unicode編譯。

位置是項目屬性 - 配置屬性 - 常規 - 字符集:使用Unicode字符集。

所有字符串文字前的L表示字符串文字是wchar_t的數組:L「Software \ ProductName」。

TCHAR是一個宏,意思是wchar_t當爲構建多字節字符集應用程序構建Unicode和`char1時。

_tcslen同樣是一個MACRO,msv c-runtine將其定義爲strlen或wcslen,具體取決於項目所選字符集。

無論如何,問題的癥結在於:wcslen返回字符串中wchar_t的個數,而註冊表函數期望數據的字節數。

這將是寫作的函數RegSetValueEx正確的方式使得字符集轉換將工作:

DWORD cch=0; 
StrCchLength(ext_id,1024,&cch); 
RegSetValueEx(hk, TEXT("ext_id"), 0, REG_SZ, (const BYTE *)ext_id, (cch + 1) * sizeof(TCHAR)); 

請注意,我從StrSafe.h而不是strlen的使用StrCchLength API,wcslen,lstrlen或相關的API。 StrCchLength和相關API具有幫助您編寫更安全的代碼的功能 - 在這種情況下,而不是執行無限注寫入註冊表,ext_id被「剪輯」爲1024個字符。

注意:您在這裏需要非常小心。某些註冊表API被記錄爲要求字節數EXCLUDE終止零,RegSetValueEx要求字節數包含零終止符。所以我給字符串的字符數加上+1,然後乘以TCHAR的大小以獲得類型的數量。


在讀數值 - 需要查詢兩倍的原因是的RegQueryValueEx使用參數lpcbData指針有兩個目的 - 作爲輸入值它指定了緩衝區的大小,並且作爲它返回數字的輸出值的實際字節寫入緩衝區(成功時)或者,如果返回碼爲ERROR_MORE_DATA,則不寫入緩衝區,但將* lpcbData設置爲所需的字節數。

TCHAR ext_id[20]; 
DWORD extIdLength = sizeof (ext_id); // you need to initialize this 
LONG err = RegQueryValueEx(hk, TEXT("ext_id"), NULL, NULL, (LPBYTE)ext_id, &extIdLength) ; 
if(err == ERROR_MORE_DATA) { 
    // you can try again here, using extIdLength to create a new buffer that IS big enough 
} 
if(err == ERROR_SUCCESS){ 
    ... 
+0

thanx的快速答覆.... 是否寫入註冊表有從中讀什麼影響嗎?我理解你所提出的所有觀點,但是我在Windows XP中從註冊表中讀取問題似乎是唯一的解決方法,就是在必要時打開並查詢密鑰兩次,以使其正常工作 最奇怪的是,當我在同一個函數中使用了AtlEscapeUrl,而RegQueryValueEx在WindowsXP中失敗了,但是在Windows7下工作,當我將這個函數移出到子函數時,它又開始工作了......這是怎麼回事? – user385342 2010-08-05 10:42:25