2011-06-13 92 views
1

Regedit Screenshot http://i54.tinypic.com/3503vi8.jpg爲什麼我的註冊表讀取程序失敗?

現在,這樣的代碼:

HKEY hKey; 
LONG regOpenCriss = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\", 0, KEY_QUERY_VALUE, &hKey); 
char mydata[2000] = {'\0'}; 
DWORD dwType = REG_SZ; 
DWORD dataLength = sizeof(mydata); 
LPVOID messagecaliss; 
GetLastError(); 
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
    NULL, GetLastError(), NULL,(LPTSTR) &messagecaliss, 0, NULL); 

if (regOpenCriss == ERROR_SUCCESS) { 
    RegQueryValueEx(hKey, "Test2", 0, &dwType, (LPBYTE)&mydata, &dataLength); //change the key you want to read 
    printf("%s\n", mydata); 
    system("PAUSE"); 
    RegCloseKey(hKey); 
} 
else 
    MessageBox(NULL,(LPCTSTR)messagecaliss,"ERROR",MB_OK|MB_ICONINFORMATION); 
printf("%s\t\n", mydata); 
std::string FullPath(mydata,dataLength-1); 
printf("%s\n", FullPath); 
std::string FileName = GetFileNameFromPath(mydata); 
printf("%s\n", FileName); 
system("PAUSE"); 

功能GetFilenameFromPath定義爲:

std::string GetFileNameFromPath (std::string str) { 
size_t found; 
found=str.find_last_of("/\\"); 
return str.substr(found+1);} 

當我打電話的RegQueryValueEx用 「QKSMTPServer3」 作爲第二個參數,這裏是輸出:

C:\Program Files (x86)\QK SMTP Server 3\QKSmtpServer3.exe 
Press any key to continue . . . 
C:\Program Files (x86)\QK SMTP Server 3\QKSmtpServer3.exe 
C:\Program Files (x86)\QK SMTP Server 3\QKSmtpServer3.exe 
QKSmtpServer3.exe 
Press any key to continue . . . 

這是我想要的。現在,當我使用「Test2」調用RegQueryValueEx時,得到:

C:\Test.exe 
Press any key to continue . . . 
C:\Test.exe 

並且程序崩潰。任何想法爲什麼?

非常感謝您

+0

函數GetFileNameFromPath取自http://www.cplusplus.com/reference/string/string/find_last_of/ – 2011-06-13 03:23:08

回答

1
  1. 你的代碼是不是異常安全的。如果std::string的成員函數拋出std::bad_alloc,則將泄漏句柄(HKEY)。
  2. 查看錯誤返回碼和GetLastError,查看代碼失敗的更具體原因。
  3. printf("%s\n", FullPath);不應該編譯,更不用說運行。你確定它不是printf("%s\n", FullPath.c_str());
  4. 而不是固定大小的緩衝區,您應該使用std::vector。如果你知道你一直會得到一個文件名,你應該使用MAX_PATH作爲你的緩衝區大小。
  5. 如果涉及Unicode字符,則此代碼將失敗。考慮將所有內容切換到wchar_t
  6. char mydata[2000] = {'\0'}; < - 爲什麼{'\0'}而不是僅僅是""{}
  7. 你不和的GetLastError();
  8. 返回代碼做任何事情如果有字符串中沒有\/GetFileNameFromPath將失敗,因爲std::string::find將返回string.npos
  9. system("PAUSE");應該替換爲std::cin.get();
+0

嘿,我添加了.c_str()部分,它的工作。非常感謝你。我不明白#1。 – 2011-06-13 03:34:10

+0

@Jack:1.不使用'cstdio'的主要原因 - 我的猜測是你正在使用一個實現,其中std :: string的第一個成員是一個指向字符串本身的指針,但是它使用小字符串優化。 2.如果拋出異常,你的代碼永遠不會進入'RegCloseKey'調用,所以你泄漏了句柄。更好地處理使用RAII類的關閉手柄。 – 2011-06-13 03:36:43