RegRegValueEx用于可能是REG_DWORD或REG_SZ的注册表值

问题描述:

当前,我正在使用RegQueryValueEx()来检索可能以REG_SZREG_DWORD格式写入的注册表值。RegRegValueEx用于可能是REG_DWORD或REG_SZ的注册表值

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(),但我不确定。

+0

关于你在问什么? – RbMm

+1

这是Unicode UTF16-LE以16位结尾0 –

您的问题与RegEnumValue()无关。

您的应用调用TCHARRegQueryValueEx(),这实际上是一个预处理宏映射到要么RegQueryValueExA()(ANSI)或RegQueryValueExW()(Unicode)的,这取决于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()或equivi借出。

  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数据(当定义UNICODE时映射到TCHAR)。

+0

太棒了!我真的想把它存储为DWORD,所以现在我将它从 'LPDWORD value = reinterpret_cast (&byteArray);' 'DWORD output = _ttoi(value);'如果有更有效的方法,请让我知道!我不太熟悉这些类型的转换 – David

+0

您不能将'REG_SZ'缓冲区投射到'LPDWORD'指针(可以,但它不会有意义),并且您无法通过指向'_ttoi()'的'LPDWORD'指针,因为它期望一个空终止的'TCHAR *'指针。而'RegQueryValueEx()'不保证输出缓冲区中会出现空终止符。因此,请改用'RegGetValue()',然后使用'LPTSTR text = reinterpret_cast (&byteArray); DWORD值= _ttoi(文本);' –