簡體   English   中英

使用RegQueryValueEx作為可能為REG_DWORD或REG_SZ的注冊表值

[英]Using RegQueryValueEx for a registry value that could be REG_DWORD or REG_SZ

當前,我正在使用RegQueryValueEx()檢索可能以REG_SZREG_DWORD格式寫入的注冊表值。

BYTE byteArray[MAX];
DWORD dataSize = sizeof(byteArray);
DWORD type = 0;
RegQueryValueEx(
        hKey,
        subKey,
        nullptr,
        &type,
        reinterpret_cast<BYTE*>(&byteArray),
        &dataSize));

當我獲得REG_SZ值的數據(例如:“ 42314”)時,我得到以下響應:

byteArray   0x004fe6a8 "4"  unsigned char[100]
    [0] 52 '4'  unsigned char
    [1] 0 '\0'  unsigned char
    [2] 50 '2'  unsigned char
    [3] 0 '\0'  unsigned char
    [4] 51 '3'  unsigned char
    [5] 0 '\0'  unsigned char
    [6] 49 '1'  unsigned char
    [7] 0 '\0'  unsigned char
    [8] 52 '4'  unsigned char
    [9] 0 '\0'  unsigned char
    [10]0 '\0'  unsigned char

有什么辦法不能讓每個字符后面都有空字節嗎? 我認為這是因為為每個字符調用了RegEnumValue() ,但是我不確定。

您的問題與RegEnumValue()無關。

您的應用程序正在調用基於TCHARRegQueryValueEx() ,它實際上是一個預處理器宏,它取決於在編譯時是否定義了UNICODE ,因此映射到RegQueryValueExA() (ANSI)或RegQueryValueExW() (Unicode)。

RegQueryValueExW()以UTF-16LE格式返回字符串數據作為Unicode文本,這正是您在緩沖區中看到的內容,因此很明顯,您的應用程序正在針對Unicode進行編譯。 您所看到的是完全正常的行為。

因此,您需要以給定的格式處理字符串數據,例如:

BYTE byteArray[MAX];
DWORD dataSize = sizeof(byteArray);
DWORD type = 0;
if (RegQueryValueEx( // <-- calling the TCHAR version!
    hKey,
    subKey,
    nullptr,
    &type,
    reinterpret_cast<BYTE*>(&byteArray),
    &dataSize) == 0)
{
    switch (type)
    {
        case REG_DWORD:
        {
            LPDWORD value = reinterpret_cast<LPDWORD>(&byteArray);
            // use *value as needed ...
            break;
        }

        case REG_SZ:
        case REG_MULTI_SZ:
        case REG_EXPAND_SZ:
        {
            // note the T in LPTSTR!  That means 'TCHAR' is used...
            LPTSTR text = reinterpret_cast<LPTSTR>(&byteArray);
            // use text as needed, up to (dataSize/sizeof(TCHAR)) number
            // of TCHARs. This is because RegQueryValueEx() does not
            // guarantee the output data has a null terminator.  If you
            // want that, use RegGetValue() instead...
            break;
        }
    }
}

要么:

BYTE byteArray[MAX];
DWORD dataSize = sizeof(byteArray);
DWORD type = 0;
if (RegQueryValueExW( // <-- calling the UNICODE version!
    hKey,
    subKey,
    nullptr,
    &type,
    reinterpret_cast<BYTE*>(&byteArray),
    &dataSize) == 0)
{
    switch (type)
    {
        case REG_DWORD:
        {
            LPDWORD value = reinterpret_cast<LPDWORD>(&byteArray);
            // use *value as needed ...
            break;
        }

        case REG_SZ:
        case REG_MULTI_SZ:
        case REG_EXPAND_SZ:
        {
            // note the W in LPWSTR!  That means 'WCHAR' is used...
            LPWSTR text = reinterpret_cast<LPWSTR>(&byteArray);
            // use text as needed, up to (dataSize/sizeof(WCHAR)) number
            // of WCHARs. This is because RegQueryValueExW() does not
            // guarantee the output data has a null terminator.  If you
            // want that, use RegGetValueW() instead...
            break;
        }
    }
}

如果要使用其他格式的文本,則必須:

  1. 將其讀取為Unicode后進行轉換,例如,使用WideCharToMultiByte()或等效方法。

  2. 直接使用RegQueryValueExA() (或RegGetValueA() ),這將根據文檔在用戶當前的語言環境中以ANSI文本的形式返回字符串數據:

    如果數據具有REG_SZREG_MULTI_SZREG_EXPAND_SZ類型,並且使用了此函數的ANSI版本(通過顯式調用RegQueryValueExA或在包括Windows.h文件之前未定義UNICODE ),則此函數會將存儲的Unicode字符串轉換為將ANSI字符串復制到lpData指向的緩沖區之前。

     BYTE byteArray[MAX]; DWORD dataSize = sizeof(byteArray); DWORD type = 0; if (RegQueryValueExA( // <-- calling the ANSI version hKey, subKey, nullptr, &type, reinterpret_cast<BYTE*>(&byteArray), &dataSize) == 0) { switch (type) { case REG_DWORD: { LPDWORD value = reinterpret_cast<LPDWORD>(&byteArray); // use *value as needed ... break; } case REG_SZ: case REG_MULTI_SZ: case REG_EXPAND_SZ: { // note the lack of T in LPSTR! That means 'char' is used... LPSTR text = reinterpret_cast<LPSTR>(&byteArray); // use text as needed, up to dataSize number of chars. This // is because RegQueryValueExA() does not guarantee the // output data has a null terminator. If you want that, // use RegGetValueA() instead... break; } } } 

無論哪種方式,請注意,您將冒丟失丟失任何要轉換為目標字符集的非ASCII字符的風險。 因此,最好改用Unicode,並將緩沖區數據作為WCHAR數據處理(定義UNICODETCHAR映射到什么)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM