RegSetValueEx - 路径错误,64 位,运行 作为管理员
RegSetValueEx - wrong path, 64bit, running as admin
我有一些关于注册表相关功能的问题。
我使用 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);
}
}
好的,这就是代码,有什么问题吗?
另外我想问一下怎么做,所以我不必 运行 它作为管理员来创建注册表,因为如果我不 运行 它作为管理员,它不会' t 创建注册表。
OS 的 64 位版本如何?我在 32 位上编译,所以我必须做些什么才能在 64 位机器上运行吗?
谢谢。 =)
您的代码有几个问题。
首先,不要硬编码文件路径,尤其是包含系统文件夹的路径。在这种情况下,您应该使用 SHGetFolderPath(CSIDL_APPDATA)
或 SHGetKnownFolderPath(FOLDERID_RoamingAppData)
来发现当前用户的 AppData\Roaming
文件夹的位置。或者,如果 MyProgram.exe
是当前 运行ning 的应用程序,您可以改用 GetModuleFileName(0)
。
其次,非管理员用户没有 HKEY_LOCAL_MACHINE
的写入权限,只有 HKEY_CURRENT_USER
。如果您需要写入 HKEY_LOCAL_MACHINE
,您的应用需要 运行 提升管理员权限。
第三,你没有正确使用RegQueryValueEx()
和RegSetValueEx()
。具体来说:
您在第一个参数中传递了错误的 HKEY
。你需要把RegOpenKeyEx()
返回给你的HKEY
传给你
对于RegSetValueEx()
,一个REG_SZ
值必须包含空终止符,但是path.size()
不包括空终止符,所以你需要使用size()+1
代替。
第四,您泄露了 RegOpenKeyEx()
返回给您的 HKEY
,因为只有 RegQueryValueEx()
成功时您才调用 RegCloseKey()
。
综上所述,试试这样的东西:
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!";
我有一些关于注册表相关功能的问题。 我使用 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);
}
}
好的,这就是代码,有什么问题吗? 另外我想问一下怎么做,所以我不必 运行 它作为管理员来创建注册表,因为如果我不 运行 它作为管理员,它不会' t 创建注册表。 OS 的 64 位版本如何?我在 32 位上编译,所以我必须做些什么才能在 64 位机器上运行吗?
谢谢。 =)
您的代码有几个问题。
首先,不要硬编码文件路径,尤其是包含系统文件夹的路径。在这种情况下,您应该使用 SHGetFolderPath(CSIDL_APPDATA)
或 SHGetKnownFolderPath(FOLDERID_RoamingAppData)
来发现当前用户的 AppData\Roaming
文件夹的位置。或者,如果 MyProgram.exe
是当前 运行ning 的应用程序,您可以改用 GetModuleFileName(0)
。
其次,非管理员用户没有 HKEY_LOCAL_MACHINE
的写入权限,只有 HKEY_CURRENT_USER
。如果您需要写入 HKEY_LOCAL_MACHINE
,您的应用需要 运行 提升管理员权限。
第三,你没有正确使用RegQueryValueEx()
和RegSetValueEx()
。具体来说:
您在第一个参数中传递了错误的
HKEY
。你需要把RegOpenKeyEx()
返回给你的HKEY
传给你对于
RegSetValueEx()
,一个REG_SZ
值必须包含空终止符,但是path.size()
不包括空终止符,所以你需要使用size()+1
代替。
第四,您泄露了 RegOpenKeyEx()
返回给您的 HKEY
,因为只有 RegQueryValueEx()
成功时您才调用 RegCloseKey()
。
综上所述,试试这样的东西:
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!";