c++ - 如何正确读取注册表中的多个值?

标签 c++ windows registry

我创建了一个 .dll,它应该像 RunAs 命令一样工作。唯一的区别是,它应该从注册表中读取。我的问题是,我需要从注册表中获取 3 个值,但我做不到。它读取第一个,然后在第二个(密码)处失败,错误代码为 2,这意味着“系统找不到指定的文件”。如果我只查询域和用户名那么没关系,如果我只查询密码那么它仍然成功,但是如果我想查询所有三个然后它失败。谁能告诉我,我做错了什么?

这是我的代码:

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

我已经在我的注册表中对许多不同的路径/项目进行了尝试,但无法重现您询问的问题。不过,我不确定这是否意味着代码可以更好地工作——我没有您正在查看的相同注册表项,因为我没有安装该特定软件。

关于c++ - 如何正确读取注册表中的多个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2485869/

相关文章:

c++ - 在 C++ 中同步时为空?

windows - 为什么此 QString 到 const char* 的转换会在 Windows 上生成 Debian 标识符?

windows - 转义批处理脚本变量中的引号

windows-8 - Windows 8 上 Internet Explorer 10 全局代理设置的注册表项

c++ - 如何从谷歌地图获取经纬度

C++ 使用 using 关键字避免派生类中的动态调度

c++ - 将 'wchar_t*' 输出到 'ofstream'

.net - 是什么阻止我的 .NET 2.0 应用程序在 64 位平台上运行?

c# - 如何从可以处理特定文件扩展名的程序列表中启动进程?

PowerShell:如何使用标准输出代替文件名