在C++中向注册表写入字符串(REG_SZ)值

25

我已经编写了大部分将值写入Windows注册表的代码,但是当我将路径更改为我设置用于测试的虚拟键和值时,它失败了。以下是我的代码:

    HKEY hKey;
    LPCTSTR sk = TEXT("SOFTWARE\TestSoftware");

    LONG openRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sk, 0, KEY_ALL_ACCESS , &hKey);

    if (openRes==ERROR_SUCCESS) {
        printf("Success opening key.");
    } else {
        printf("Error opening key.");
    }

    LPCTSTR value = TEXT("TestSoftwareKey");
    LPCTSTR data = "TestData\0";

    LONG setRes = RegSetValueEx (hKey, value, 0, REG_SZ, (LPBYTE)data, strlen(data)+1);

    if (setRes == ERROR_SUCCESS) {
        printf("Success writing to Registry.");
    } else {
        printf("Error writing to Registry.");
    }

    LONG closeOut = RegCloseKey(hKey);

    if (closeOut == ERROR_SUCCESS) {
        printf("Success closing key.");
    } else {
        printf("Error closing key.");
    }

这三个测试都返回错误状态。

让我困惑的是,当我将代码指向注册表的其他部分时,我能够运行它。有什么想法吗?

谢谢, 布赖恩


2
请注意,RegSetValueEx函数将字符串长度以字节(而不是字符)的形式作为其最后一个参数。因此,最好使用StringCbLength而不是strlen - Felix Dombek
3个回答

39

我感到有点傻。解决方法是需要正确转义字符串中的斜杠,如下所示:

LPCTSTR sk = TEXT("SOFTWARE\\TestSoftware");

希望这对某人有用...


3
从VC++ 2013开始,可以使用LR"("SOFTWARE\TestSoftware")"这种形式的“原始字符串字面量”(raw string literals)。 - MSalters

6
HKEY OpenKey(HKEY hRootKey, char* strKey)
{
  HKEY hKey;
  LONG nError = RegOpenKeyEx(hRootKey, strKey, NULL, KEY_ALL_ACCESS, &hKey);

  if (nError==ERROR_FILE_NOT_FOUND)
  {
    cout << "Creating registry key: " << strKey << endl;
    nError = RegCreateKeyEx(hRootKey, strKey, NULL, NULL,     REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL, &hKey, NULL);
  }

  if (nError)
    cout << "Error: " << nError << " Could not find or create " <<      strKey << endl;

  return hKey;
}

void SetintVal(HKEY hKey, LPCTSTR lpValue, DWORD data)
{
  LONG nError = RegSetValueEx(hKey, lpValue, NULL, REG_DWORD,   (LPBYTE)&data, sizeof(DWORD));

  if (nError)
      cout << "Error: " << nError << " Could not set registry value: " << (char*)lpValue << endl;
}

DWORD GetintVal(HKEY hKey, LPCTSTR lpValue)
{
  DWORD data;
  DWORD size = sizeof(data);
  DWORD type = REG_DWORD;
  LONG nError = RegQueryValueEx(hKey, lpValue, NULL, &type, (LPBYTE)&data, &size);

  if (nError==ERROR_FILE_NOT_FOUND)
     data = 0; 
  SetVal() is called.
  else if (nError)
    cout << "Error: " << nError << " Could not get registry value " << (char*)lpValue << endl;

  return data;
}

BOOL SetcharVal(HKEY Key,char* subkey,char* StringName,char* Stringdata)
{
  HKEY hKey = OpenKey(Key,subkey);

  LONG openRes = RegOpenKeyEx(Key, subkey, 0, KEY_ALL_ACCESS , &hKey);

  if (openRes==ERROR_SUCCESS) {

  } else {
    printf("Error opening key.");
  }

  LONG setRes = RegSetValueEx (hKey, StringName, 0, REG_SZ, (LPBYTE)Stringdata, strlen(Stringdata)+1);

  if (setRes == ERROR_SUCCESS) {

  } else {
    printf("Error writing to Registry.");
  }

  LONG closeOut = RegCloseKey(hKey);

  if (closeOut == ERROR_SUCCESS) {

  } else {
    printf("Error closing key.");
  }

}

char* GetCharVal(HKEY Key,char* subkey,char* StringName)
{
  DWORD dwType = REG_SZ;
  HKEY hKey = 0;
  char value[1024];
  DWORD value_length = 1024;
  RegOpenKey(HKEY_LOCAL_MACHINE,subkey,&hKey);
  RegQueryValueEx(hKey, StringName, NULL, &dwType, (LPBYTE)&value,     &value_length);
  RegCloseKey(hKey);
  return value;
}

我正在使用这段代码。

1
请直接编辑您之前的代码,而不是在问题下发布第二个答案。 - Richard Erickson
1
请考虑编辑您的答案,包括解释您的代码如何解决手头的问题。 - Matt

1

对于 UNICODE 环境:

//Writing to registry
HKEY hKey;
LPCTSTR sk = TEXT("SOFTWARE\\Microsoft\\Windows");

LONG openRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sk, 0, KEY_ALL_ACCESS, &hKey);

if (openRes == ERROR_SUCCESS) {
    printf("Success opening key.");
}
else {
    printf("Error opening key.");
}

LPCTSTR value = TEXT("Sample");
WCHAR path[80] = TEXT("C:\\samples\\app.exe");

LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ, (LPBYTE)path, sizeof(path));

if (setRes == ERROR_SUCCESS) {
    printf("Success writing to Registry.");
}
else {
    printf("Error writing to Registry.");
}

LONG closeOut = RegCloseKey(hKey);

if (closeOut == ERROR_SUCCESS) {
    printf("Success closing key.");
}
else {
    printf("Error closing key.");
}

虽然 sizeof(path) 肯定足够大,但我认为你想要的不是 sizeof(path),而是 wcslen(path) * sizeof(WCHAR)。这也足够大以容纳整个字符串。在我的代码中,我将 LPCWSTR i_lpStringValue 传递给我的函数,并使用 wcslen(i_lpStringValue) * sizeof(wchar_t) 作为 RegSetValueEx 函数的 cbData 参数。它似乎保存了所有字符。如果我有什么误解,请随时纠正我。 - Rocky Scott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接