項目中需要讀取注冊表中的HKEY_CLASSES_ROOT主鍵下一個子鍵的值,看了看MSDN的說明,有RegOpenKeyEx和RegQueryValueEx兩個函數可以用。也沒仔細閱讀函數說明,就寫了一段簡單的代碼來測試:
HKEY hKey; WCHAR szLocation[MAX_PATH] = {'\0'}; DWORD dwSize = sizeof(DWORD); DWORD dwType = REG_SZ; LPCTSTR studioPath = TEXT("insta360\\studio"); LONG ret; ret = RegOpenKeyEx(HKEY_CLASSES_ROOT, studioPath, 0, KEY_READ, &hKey); wprintf(L"RegOpenKeyEx returns %d\n", ret); if (ERROR_SUCCESS == ret) { ret = RegQueryValueEx(hKey, TEXT("install_location"), 0, &dwType, (LPBYTE)&szLocation, &dwSize); wprintf(L"RegQueryValueEx returns %d, dwSize=%d\n", ret, dwSize); if (ERROR_SUCCESS == ret) { wprintf(L"Location: %s", szLocation); } RegCloseKey(hKey); }
一運行才發現啥也沒讀出來,而RegQueryValueEx()竟然返回的是234(ERROR_MORE_DATA),頓時一臉懵逼。
網上一搜才知道,關鍵的關鍵在於這個函數的最后一個參數。其類型標注為[in][out]。也就是說,這個參數既作為函數的輸入,也作為函數的輸出。函數在讀取注冊表時會將實際需要的空間大小存在這個參數中。用戶根據這個大小再來分配需要的內存空間。所以程序在正式讀取之前,可以調用這個函數試探一下大小:
HKEY hKey; WCHAR szLocation[MAX_PATH] = {'\0'}; DWORD dwSize = sizeof(DWORD); DWORD dwType = REG_SZ; LPCTSTR studioPath = TEXT("insta360\\studio"); LONG ret; ret = RegOpenKeyEx(HKEY_CLASSES_ROOT, studioPath, 0, KEY_READ, &hKey); wprintf(L"RegOpenKeyEx returns %d\n", ret); if (ERROR_SUCCESS == ret) { ret = RegQueryValueEx(hKey, TEXT("install_location"), 0, &dwType, NULL, &dwSize); wprintf(L"RegQueryValueEx returns %d, dwSize=%d\n", ret, dwSize); ret = RegQueryValueEx(hKey, TEXT("install_location"), 0, &dwType, (LPBYTE)&szLocation, &dwSize); wprintf(L"RegQueryValueEx returns %d, dwSize=%d\n", ret, dwSize); if (ERROR_SUCCESS == ret) { wprintf(L"Location: %s\n", szLocation); } RegCloseKey(hKey); }
注意試探的時候,這個函數的倒數第二個參數應該傳遞NULL。但實際上也可以不試探。而是將最后一個參數的輸入值設置大一點,這樣就不會返回234錯誤代碼了。
參考鏈接
https://www.experts-exchange.com/questions/23897919/RegQueryValueEx-causes-Error-234.html