我有一些与注册表相关的功能相关的问题。 我使用RegSetValueEx函数来创建一个注册表数据但不幸的是我确实做错了但我不确定,错误在哪里。我想在HKEY_LOCAL_MACHINE - SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run中创建一个注册表,但它只在HKEY_LOCAL_MACHINE键中创建数据,并且全部都是。
TCHAR name[UNLEN + 1];
DWORD size = UNLEN + 1;
GetUserName((TCHAR*)name, &size);
string namep = name;
string path = "C:\\Users\\" + namep + "\\AppData\\Roaming\\MyProgram\\MyProgram.exe";
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
cout << "OPENED!";
if (RegQueryValueEx(HKEY_LOCAL_MACHINE, "MyRegistry", 0, NULL, NULL, NULL) == ERROR_FILE_NOT_FOUND)
{
cout << "NOT FOUND!"; // If registry not found, then create it?
if (RegSetValueEx(HKEY_LOCAL_MACHINE, "MyRegistry", 0, REG_SZ, (const BYTE*)path.c_str(), path.size()) == ERROR_SUCCESS)
cout << "REGISTRY WRITTEN";
RegCloseKey(hKey);
}
}
好的,这就是代码,出了什么问题? 另外我想问一下如何做,所以我不必以管理员的身份运行它来创建注册表,因为如果我不以管理员的身份运行它,它就不会创建注册表。 64位版本的操作系统如何?我在32位编译,所以有什么我必须做的,所以它适用于64位机器吗?
感谢。 =)
答案 0 :(得分:2)
您的代码存在一些问题。
首先,不要对文件路径进行硬编码,尤其是包含系统文件夹的路径。在这种情况下,您应该使用SHGetFolderPath(CSIDL_APPDATA)
或SHGetKnownFolderPath(FOLDERID_RoamingAppData)
来发现当前用户的AppData\Roaming
文件夹的位置。或者,如果MyProgram.exe
是当前正在运行的应用,则可以改为使用GetModuleFileName(0)
。
其次,非管理员用户对HKEY_LOCAL_MACHINE
没有写入权限,只有HKEY_CURRENT_USER
。如果您需要写信至HKEY_LOCAL_MACHINE
,您的应用需要使用提升的管理员权限运行。
第三,您没有正确使用RegQueryValueEx()
和RegSetValueEx()
。具体做法是:
您在第一个参数中传递了错误的HKEY
。您需要传递HKEY
返回给您的RegOpenKeyEx()
。
RegSetValueEx()
,,REG_SZ
值必须包含空终止符,但path.size()
不计算空终止符,因此您需要使用size()+1
代替
第四,您正在泄露HKEY
返回给您的RegOpenKeyEx()
,因为只有在RegCloseKey()
成功时才拨打RegQueryValueEx()
。
所有这些都说,尝试更像这样的事情:
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
cout << "OPENED! ";
LONG lRet = RegQueryValueEx(hKey, TEXT("MyRegistry"), 0, NULL, NULL, NULL);
if (lRet == ERROR_FILE_NOT_FOUND)
{
cout << "NOT FOUND! ";
// assuming you want to store the calling process's
// filename, otherwise adjust this as needed ...
TCHAR filename[MAX_PATH + 1];
DWORD len = GetModuleFileName(NULL, filename, MAX_PATH);
filename[len] = 0;
if (RegSetValueEx(hKey, TEXT("MyRegistry"), 0, REG_SZ, (const BYTE*)filename, (len+1) * sizeof(TCHAR)) == ERROR_SUCCESS)
cout << "WRITTEN!";
else
cout << "NOT WRITTEN!";
}
else if (lRet == 0)
{
cout << "FOUND!";
}
else
cout << "NOT QUERIED!";
RegCloseKey(hKey);
}
else
cout << "NOT OPENED!";
如果您只想确保注册表包含最新的文件名,您可以省略RegQueryValueEx()
并让RegSetValueEx()
覆盖现有值(如果存在):
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
cout << "OPENED! ";
// assuming you want to store the calling process's
// filename, otherwise adjust this as needed ...
TCHAR filename[MAX_PATH + 1];
DWORD len = GetModuleFileName(NULL, filename, MAX_PATH);
filename[len] = 0;
if (RegSetValueEx(hKey, TEXT("MyRegistry"), 0, REG_SZ, (const BYTE*)filename, (len+1) * sizeof(TCHAR)) == ERROR_SUCCESS)
cout << "WRITTEN!";
else
cout << "NOT WRITTEN!";
RegCloseKey(hKey);
}
else
cout << "NOT OPENED!";