C++ 如何在c中正确读取多个值的注册表?
我创建了一个.dll,它应该像RunAs命令一样工作。唯一的区别是,它应该从注册表中读取。我的问题是,我需要从注册表中提取3个值,但我不能。它读取第一个文件,而读取第二个文件(密码)失败,错误代码为2,这意味着“系统找不到指定的文件”。若我只查询域和用户名,那个么它是可以的,若我只查询密码,那个么它仍然成功,但若我想查询所有三个,那个么它就失败了。谁能告诉我,我做错了什么 这是我的密码:C++ 如何在c中正确读取多个值的注册表?,c++,windows,registry,C++,Windows,Registry,我创建了一个.dll,它应该像RunAs命令一样工作。唯一的区别是,它应该从注册表中读取。我的问题是,我需要从注册表中提取3个值,但我不能。它读取第一个文件,而读取第二个文件(密码)失败,错误代码为2,这意味着“系统找不到指定的文件”。若我只查询域和用户名,那个么它是可以的,若我只查询密码,那个么它仍然成功,但若我想查询所有三个,那个么它就失败了。谁能告诉我,我做错了什么 这是我的密码: HKEY hKey = 0; DWORD dwType = REG_SZ; DWORD dwBufS
HKEY hKey = 0;
DWORD dwType = REG_SZ;
DWORD dwBufSize = sizeof(buf);
TCHAR szMsg [MAX_PATH + 32];
HANDLE handle;
LPVOID lpMsgBuf;
if( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("SOFTWARE\\Kampi Corporation\\RunAs!"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
if( RegQueryValueEx( hKey, TEXT("Username"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )
{
memset( szMsg, 0, sizeof( szMsg ) );
wsprintf ( szMsg, _T("%s"), buf );
mbstowcs( wuser, szMsg, 255 );
RegCloseKey( hKey );
}
else
{
MessageBox ( pCmdInfo->hwnd, "Can not query for Username key value!", _T("RunAs!"), MB_ICONERROR );
RegCloseKey( hKey );
return -1;
}
}
else
{
CSimpleShlExt::showerror( GetLastError(), pCmdInfo->hwnd, "RegOpenKeyEx failed for Username with error code :: " );
return -1;
}
if( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("SOFTWARE\\Kampi Corporation\\RunAs!"), 0, KEY_QUERY_VALUE ,&hKey ) == ERROR_SUCCESS )
{
if( RegQueryValueEx( hKey, TEXT("Password"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )
{
memset( szMsg, 0, sizeof( szMsg ) );
wsprintf ( szMsg, _T("%s"), buf );
mbstowcs( wpass, szMsg, 255 );
RegCloseKey( hKey );
}
else
{
char test[200];
sprintf(test,"Can not query for Password key value! EC: %d",GetLastError() );
MessageBox ( pCmdInfo->hwnd, test, _T("RunAs!"), MB_ICONERROR );
RegCloseKey( hKey );
return -1;
}
}
else
{
CSimpleShlExt::showerror( GetLastError(), pCmdInfo->hwnd, "RegOpenKeyEx failed for Password with error code :: " );
return -1;
}
if( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("SOFTWARE\\Kampi Corporation\\RunAs!"), 0, KEY_QUERY_VALUE ,&hKey ) == ERROR_SUCCESS )
{
if( RegQueryValueEx( hKey, TEXT("Domain"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )
{
memset( szMsg, 0, sizeof( szMsg ) );
wsprintf ( szMsg, _T("%s"), buf );
mbstowcs( wdomain, szMsg, 255 );
RegCloseKey( hKey );
}
else
{
sprintf(test,"Can not query for Password key value! EC: %d",GetLastError() );
MessageBox ( pCmdInfo->hwnd, test, _T("RunAs!"), MB_ICONERROR );
RegCloseKey( hKey );
return -1;
}
}
else
{
CSimpleShlExt::showerror( GetLastError(), pCmdInfo->hwnd, "RegOpenKeyEx failed for Domain with error code :: " );
return -1;
}
虽然它与您所问的问题没有直接关系,但我认为诊断问题的第一步是消除代码中的一些重复。现在,几乎不可能确保所有查询都以相同的方式工作。这是一个很好的例子,说明了如果编程编辑器根本没有剪切或(特别是)粘贴命令,它可能会更好。我想我应该从这样的代码开始:
#include <windows.h>
#include <string>
#include <sstream>
#include <iostream>
#include <exception>
#include <iterator>
namespace {
void check(DWORD value, char const *op) {
if (value != ERROR_SUCCESS) {
std::ostringstream buf;
buf << op << " failed error code = " << value;
throw std::logic_error(buf.str().c_str());
}
}
class reg_key {
HKEY key;
public:
reg_key(wchar_t const *path, HKEY topkey = HKEY_CURRENT_USER, DWORD q=KEY_QUERY_VALUE) {
check(RegOpenKeyExW(topkey, path, 0, q, &key), "RegOpenKeyExW");
}
operator HKEY() { return key; }
~reg_key() { RegCloseKey(key); }
};
}
template <class outIt>
void read_reg(wchar_t const *path, wchar_t const *name, outIt out) {
static const int buf_size = 256;
wchar_t buffer[buf_size];
DWORD size = buf_size, type = REG_SZ;
reg_key key(path);
check(RegQueryValueExW(key, name, 0, &type, (LPBYTE)buffer, &size), "RegQueryValueExW");
std::copy(buffer, buffer+wcslen(buffer), out);
}
#ifdef TEST
int main() {
std::wstring code_page, font;
try {
read_reg(L"Software\\Microsoft\\CharMap", L"CodePage", std::back_inserter(code_page));
read_reg(L"Software\\Microsoft\\CharMap", L"Font", std::back_inserter(font));
std::wcout << "Code Page: " << code_page << "\n";
std::wcout << "Font: " << font << std::endl;
}
catch (std::exception &e) {
MessageBox(NULL, e.what(), "Reading Registry failed", MB_ICONERROR);
}
return 0;
}
#endif
#包括
#包括
#包括
#包括
#包括
#包括
命名空间{
无效检查(DWORD值,字符常量*op){
如果(值!=错误\u成功){
std::ostringstream buf;
buf虽然这与您所问的问题没有直接关系,但我认为诊断问题的第一步是消除代码中的一些重复。现在,几乎不可能确保所有查询都以相同的方式工作。这是一个很好的例子,说明了为什么编程编辑器使用我根本没有剪切或(特别是)粘贴命令。我想我应该从以下代码开始:
#include <windows.h>
#include <string>
#include <sstream>
#include <iostream>
#include <exception>
#include <iterator>
namespace {
void check(DWORD value, char const *op) {
if (value != ERROR_SUCCESS) {
std::ostringstream buf;
buf << op << " failed error code = " << value;
throw std::logic_error(buf.str().c_str());
}
}
class reg_key {
HKEY key;
public:
reg_key(wchar_t const *path, HKEY topkey = HKEY_CURRENT_USER, DWORD q=KEY_QUERY_VALUE) {
check(RegOpenKeyExW(topkey, path, 0, q, &key), "RegOpenKeyExW");
}
operator HKEY() { return key; }
~reg_key() { RegCloseKey(key); }
};
}
template <class outIt>
void read_reg(wchar_t const *path, wchar_t const *name, outIt out) {
static const int buf_size = 256;
wchar_t buffer[buf_size];
DWORD size = buf_size, type = REG_SZ;
reg_key key(path);
check(RegQueryValueExW(key, name, 0, &type, (LPBYTE)buffer, &size), "RegQueryValueExW");
std::copy(buffer, buffer+wcslen(buffer), out);
}
#ifdef TEST
int main() {
std::wstring code_page, font;
try {
read_reg(L"Software\\Microsoft\\CharMap", L"CodePage", std::back_inserter(code_page));
read_reg(L"Software\\Microsoft\\CharMap", L"Font", std::back_inserter(font));
std::wcout << "Code Page: " << code_page << "\n";
std::wcout << "Font: " << font << std::endl;
}
catch (std::exception &e) {
MessageBox(NULL, e.what(), "Reading Registry failed", MB_ICONERROR);
}
return 0;
}
#endif
#包括
#包括
#包括
#包括
#包括
#包括
命名空间{
无效检查(DWORD值,字符常量*op){
如果(值!=错误\u成功){
std::ostringstream buf;
buf我想我知道原因了。每次调用RegQueryValueEx之前都需要初始化dwBufSize。此函数返回复制到buf的字节数
您会发现该函数返回错误\u更多\u数据。您犯了使用GetLastError()的错误。不要这样做。Reg函数直接返回错误代码。我想我可以理解原因。您需要在每次调用RegQueryValueEx之前初始化dwBufSize。此函数返回复制到buf的字节数
您将发现函数返回错误\u更多\u数据。您犯了使用GetLastError()的错误。不要这样做。Reg函数直接返回错误代码。嗨!非常感谢。这是我的问题。我只需要在每次查询之前初始化dwBufSize。非常感谢!非常感谢。这是我的问题。我只需要在每次查询之前初始化dwBufSize。非常感谢much@Jerry:非常感谢你你的帮助。我也试过你的代码,它运行得很好,但在这种情况下,在我的代码中放两行代码比重写整个代码更容易。不幸的是,我只能接受一个解决方案,所以这次是rich,但再次感谢你:)@Jerry:非常感谢你的帮助。我也试过你的代码,它运行得很好,但在这种情况下,它是正确的在我的代码中放两行代码比重写整个代码更容易。不幸的是,我只能接受一个解决方案,所以这次它适用于rich,但再次感谢:)