2016-06-10 24 views
0

當我在g ++上運行此代碼時,它運行平穩,但是當我在Visual Studio上使用unicode字符集選項運行此代碼時,它不會打印產品ID。 你能解釋我如何解決這個問題,爲什麼會發生?爲什麼這段代碼在帶有多字節字符集的visual studio中完美運行,但沒有使用unicode字符集?

#include <windows.h> 
#include <stdio.h> 
#include <iostream> 
using namespace std; 

wchar_t* GetRegistryKeyValue(const char* RegKey, const char* pPIDName) 
{ 
    HKEY  Registry; 
    long  ReturnStatus; 
    DWORD  regType = 0; 
    DWORD  regSize = 0; 
    char*  pPID = 0; 
    ReturnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegKey, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &Registry); 
    if (ReturnStatus == ERROR_SUCCESS) 
    { 
     ReturnStatus = RegQueryValueEx(Registry, pPIDName, 0, &regType, 0, &regSize); 
     pPID = new char[regSize]; 

     /* Get Value. */ 
     ReturnStatus = RegQueryValueEx(Registry, pPIDName, 0, &regType, (LPBYTE)pPID, &regSize); 


     RegCloseKey(Registry); 

     if (pPID[regSize] > 127 || pPID[regSize] < 32) 
     { 
      pPID[regSize] = '\0'; 
     } 

     if (regSize > 1) 
     { 

      int s = 0; 
      int i=0; 
      while (pPID[i] != NULL) 
      { 
       s++; 
       i++; 
      } 


      const size_t cSize = s ; 
      wchar_t* wc = new wchar_t[cSize]; 
      mbstowcs(wc, pPID, cSize); 

      return wc; 
     } 
     else 
     { 
      printf("Size not > 1 (%d)\n", regSize); 
      return NULL; 
     } 
    } 
    else 
    { 
     RegCloseKey(Registry); 
     return NULL; 
    } 
} 
int main() 
{ 
    wchar_t * resultData=NULL; 
    resultData = GetRegistryKeyValue("SOFTWARE\\MICROSOFT\\Windows NT\\CurrentVersion", "ProductId"); 
    wcout << resultData; 
    cout << endl; 
    delete resultData; 
    system("PAUSE"); 
    return 0; 
} 
+0

你是幸運的,如果這似乎在所有的工作。在使用'new []'分配的指針上調用'delete'是未定義的行爲。然而,你真正的問題是你重新解釋ANSI編碼的字符串,就好像它們是UTF-16一樣。 – IInspectable

+0

當選擇unicode字符集選項時,prepecasting RegKey和pPID與lpcwstr似乎很好,沒有語法錯誤,但RegQueryValueEx在這種情況下返回2,這不應該發生。 – usamamw141

+0

如果'pPID = new char [regSize]'那麼肯定'pPID [regSize]'超出邊界? – kfsone

回答

1

您在使用基於TCHAR的API時,在爲Unicode編譯時編譯MBCS和wchar_t*數據時依賴於char*數據。您沒有正確考慮這一差異。設置爲Unicode時,您的代碼甚至不應編譯,因爲您將ANSI參數傳遞給Unicode函數。既然你想返回一個Unicode字符串,你應該首先使用Unicode API函數。

有代碼中的其他邏輯錯誤,如內存泄漏,不爲wc緩衝,錯誤處理不夠分配字節的正確數量等

嘗試一些更喜歡這個:

#include <windows.h> 
#include <stdio.h> 
#include <iostream> 

using namespace std; 

wchar_t* GetRegistryKeyValue(const wchar_t* RegKey, const wchar_t* pValueName) 
{ 
    long  ReturnStatus; 
    DWORD  regType = 0; 
    DWORD  regSize = 0; 
    DWORD dwFlags = RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ | RRF_RT_REG_EXPAND_SZ | RRF_SUBKEY_WOW6464KEY; 
    wchar_t* ws = 0; 

    ReturnStatus = RegGetValueW(HKEY_LOCAL_MACHINE, RegKey, pValueName, dwFlags, &regType, 0, &regSize); 
    if (ReturnStatus == ERROR_SUCCESS) 
    { 
     ws = new wchar_t[regSize/sizeof(WCHAR)]; 

     ReturnStatus = RegGetValueW(HKEY_LOCAL_MACHINE, RegKey, pValueName, dwFlags, &regType, ws, &regSize); 
     if (ReturnStatus != ERROR_SUCCESS) 
     { 
      delete[] ws; 
      ws = NULL; 
     } 
    } 

    return ws; 
} 

int main() 
{ 
    wchar_t* resultData = GetRegistryKeyValue(L"SOFTWARE\\MICROSOFT\\Windows NT\\CurrentVersion", L"ProductId"); 
    wcout << resultData << endl; 
    delete[] resultData; 
    system("PAUSE"); 
    return 0; 
} 

或者:

#include <windows.h> 
#include <stdio.h> 
#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

wstring GetRegistryKeyValue(const wchar_t* RegKey, const wchar_t* pValueName) 
{ 
    long  ReturnStatus; 
    DWORD  regType = 0; 
    DWORD  regSize = 0; 
    DWORD dwFlags = RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ | RRF_RT_REG_EXPAND_SZ | RRF_SUBKEY_WOW6464KEY; 

    ReturnStatus = RegGetValueW(HKEY_LOCAL_MACHINE, RegKey, pValueName, dwFlags, &regType, 0, &regSize); 
    if (ReturnStatus == ERROR_SUCCESS) 
    { 
     vector<BYTE> buf; 
     buf.resize(regSize); 

     ReturnStatus = RegGetValueW(HKEY_LOCAL_MACHINE, RegKey, pValueName, dwFlags, &regType, &buf[0], &regSize); 
     if (ReturnStatus == ERROR_SUCCESS) 
      return wstring((wchar_t*)&buf[0], (regSize/sizeof(WCHAR)) - 1); 
    } 

    return wstring(); 
} 

int main() 
{ 
    wcout << GetRegistryKeyValue(L"SOFTWARE\\MICROSOFT\\Windows NT\\CurrentVersion", L"ProductId") << endl; 
    system("PAUSE"); 
    return 0; 
} 
+0

ReturnStatus = RegGetValueW(HKEY_LOCAL_MACHINE,RegKey,pValueName,dwFlags,&regType,&ws [0],&regSize); &ws [0]中有錯誤。 – usamamw141

+0

你的第一個代碼沒有工作,RRF_SUBKEY_WOW6464KEY標誌給了我一個Visual Studio中的錯誤,而我使用它的十六進制值,它的工作原理! – usamamw141

+0

我用十六進制值替換了標誌。 – usamamw141

0

根據此文件:

http://www.cplusplus.com/reference/cstdlib/mbstowcs/

如果最大字符成功轉換,存儲在dest的字符串不是空終止。

你想計算字符串長度(其中,順便說一句,可以通過更換strlen(pPID))將跳過'\0'第一個字符串中,因此結果可能不會對最終'\0'棘手的方式。你爲什麼不在那裏使用regSize

+0

我面臨的主要問題是,當我使用const的類型轉換 char * RegKey,const char * pPIDName to lpcwstr, pPID [regsize]設置爲null。 我希望在pPID []中使用visual studio中的unicode cha set設置打開windows pid。 – usamamw141

相關問題