2

There is a REG_MULTI_SZ value that I would like to stick in an array of strings so that my program can do other things with them. I've never used C++ to access the registry so I'm a bit lost after following some examples. I'm using VS10.

Is there a simple way to do this? Thanks.

Aaron Klotz
  • 11,287
  • 1
  • 28
  • 22
itslittlejohn
  • 1,808
  • 3
  • 20
  • 33

1 Answers1

5

First: run RegQueryValueEx to get type and necessary memory size:

Single byte code:

DWORD type, size;
vector<string> target;
if ( RegQueryValueExA(
    your_key, // HKEY
    TEXT("ValueName"),
    NULL,
    &type,
    NULL,
    &size ) != ERROR_SUCCESS )
  return;
if ( type == REG_MULTI_SZ )
{
  vector<char> temp(size);

  if ( RegQueryValueExA(
      your_key, // HKEY
      TEXT("ValueName"),
      NULL,
      NULL,
      reinterpret_cast<LPBYTE>(&temp[0]),
      &size ) != ERROR_SUCCESS )
  return;

  size_t index = 0;
  size_t len = strlen( &temp[0] );
  while ( len > 0 )
  {
    target.push_back(&temp[index]);
    index += len + 1;
    len = strlen( &temp[index] );
  }
}

Unicode:

DWORD type, size;
vector<wstring> target;
if ( RegQueryValueExW(
    your_key, // HKEY
    TEXT("ValueName"),
    NULL,
    &type,
    NULL,
    &size ) != ERROR_SUCCESS )
  return;
if ( type == REG_MULTI_SZ )
{
  vector<wchar_t> temp(size/sizeof(wchar_t));

  if ( RegQueryValueExW(
      your_key, // HKEY
      TEXT("ValueName"),
      NULL,
      NULL,
      reinterpret_cast<LPBYTE>(&temp[0]),
      &size ) != ERROR_SUCCESS )
  return;

  size_t index = 0;
  size_t len = wcslen( &temp[0] );
  while ( len > 0 )
  {
    target.push_back(&temp[index]);
    index += len + 1;
    len = wcslen( &temp[index] );
  }
}
Naszta
  • 7,560
  • 2
  • 33
  • 49
  • What you have doesn't quite work. Would you mind helping me understand a little better? Right now size is not defined, and VS10 says there are too many arguments for the RegQueryValueEx function. One too many, it looks like. Also, what would be an example of what to put instead of your_key? Thanks for the help! – itslittlejohn Jul 19 '11 at 16:35
  • @itslittlejohn: the first `RegQueryValueEx` get the size and the type of the registry value. If these values successfully read, than I read the data from the key. In [MSDN](http://msdn.microsoft.com/en-us/library/ms724911(v=VS.85).aspx) you could check all of the parameters of `RegQueryValueEx`. – Naszta Jul 19 '11 at 18:34
  • Thanks. That's what I figured so I supplied the cast and it worked. If I use the following code instead of yours that starts with size_t index, I can get the buffer out, but I can't seem to get your while loop to work. for(DWORD i = 0; i < size; i++) { cout << tempV[i]; } – itslittlejohn Jul 22 '11 at 13:54
  • nevermind! I got it. Perfect. The only thing I changed was I had to cast the &temp[index] to (char*). Then it works perfectly. – itslittlejohn Jul 22 '11 at 14:05
  • For me this code gets only the first value from the REG_MULTI_SZ on which I tried. I digged a bit: the temp char vector contains all the things, so the result gets cut later. I don't exactly know why it gets cut, but I ended up iterating the `char` vector itself and putting stuff in a `string` vector, "cutting" strings on `'\0'`. Is it expected that this code cuts the things this way? – reallynice Sep 30 '15 at 13:40
  • @reallynic: you shouldn't pass through std::string to a C function: only vector and array are guaranteed to be continuous. – Naszta Sep 30 '15 at 19:38