如何用C++打开注册表

如何用C++打开注册表,c++,windows,winapi,C++,Windows,Winapi,我正在寻找打开注册表编辑器并显示某些特定键或值的方法。例如,如果我通过HKLM\\SOFTWARE\\Skype\\Installer,我希望得到这样的结果: 欢迎除系统调用之外的所有建议。只需调用系统即可。用陈雷蒙的话来说:。任何相关的攻击都需要破坏机器,使系统调用完全不相关。事实上,任何可以更改RegEdit的攻击者也可以更改您的程序,因此他可以添加该系统调用。他不会的,因为这是毫无意义的这是我需要的 String GetFullHKEY (HKEY hKeyRoot) { if (

我正在寻找打开注册表编辑器并显示某些特定键或值的方法。例如,如果我通过HKLM\\SOFTWARE\\Skype\\Installer,我希望得到这样的结果:


欢迎除系统调用之外的所有建议。

只需调用系统即可。用陈雷蒙的话来说:。任何相关的攻击都需要破坏机器,使系统调用完全不相关。事实上,任何可以更改RegEdit的攻击者也可以更改您的程序,因此他可以添加该系统调用。他不会的,因为这是毫无意义的

这是我需要的

String GetFullHKEY (HKEY hKeyRoot)
{
    if (HKEY_LOCAL_MACHINE == hKeyRoot) return _T("HKEY_LOCAL_MACHINE\\");
    if (HKEY_CLASSES_ROOT == hKeyRoot) return _T("HKEY_CLASSES_ROOT\\");
    if (HKEY_CURRENT_CONFIG == hKeyRoot) return _T("HKEY_CURRENT_CONFIG\\");
    if (HKEY_CURRENT_USER == hKeyRoot) return _T("HKEY_CURRENT_USER\\");
    if (HKEY_USERS == hKeyRoot) return _T("HKEY_USERS\\");
}

bool RegistryGoTo (HKEY hKeyRoot, const String &lpctPath, String lpctValue)
{
    if (lpctPath.empty() || 0 == hKeyRoot) 
        return false;
    if( lpctValue.empty() && lpctValue.empty() == 0)
    {
        lpctValue.clear();
    }

    SHELLEXECUTEINFO shi = { 0 };
    DEVMODE dm = { 0 };

    HWND hWndRegedit = ::FindWindow (_T("RegEdit_RegEdit"), NULL);
    if (NULL == hWndRegedit)
    {
        shi.cbSize = sizeof(SHELLEXECUTEINFO);
        shi.fMask  = SEE_MASK_NOCLOSEPROCESS; 
        shi.lpVerb = _T("open"); 
        shi.lpFile = _T("regedit.exe"); 
        shi.nShow  = SW_SHOWNORMAL; 

        ShellExecuteEx (&shi);
        if( GetLastError() != 0 )
        {
            Sleep(200);
            ShellExecuteEx (&shi);
        }
        WaitForInputIdle (shi.hProcess, INFINITE);

        hWndRegedit = ::FindWindow (_T("RegEdit_RegEdit"), NULL);
    }

    if (NULL == hWndRegedit) return FALSE;

    SetForegroundWindow (hWndRegedit);
    ShowWindow (hWndRegedit, SW_SHOWNORMAL);

    HWND hWndTreeView = FindWindowEx (hWndRegedit, NULL, _T ("SysTreeView32"), NULL);
    SetForegroundWindow (hWndTreeView);
    SetFocus (hWndTreeView);

    for (int i = 0; i < 30; i++)
    {
        SendMessage (hWndTreeView, WM_KEYDOWN, VK_LEFT, 0);
    } 

    dm.dmSize = sizeof (DEVMODE);
    EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &dm);

    if (8 < dm.dmBitsPerPel) Sleep (100);

    // the path must start with a backslash
    String stRegPath = String (_T("\\")) + GetFullHKEY(hKeyRoot) + lpctPath;

    // open path
    for (int iIndex = 0; iIndex < (int) stRegPath.length (); iIndex++)
    {
        if (_T('\\') == stRegPath [iIndex])  
        {
            SendMessage (hWndTreeView, WM_KEYDOWN, VK_RIGHT, 0);

            if (8 < dm.dmBitsPerPel) 
                Sleep (100);
        } 
        else SendMessage (hWndTreeView, WM_CHAR, toupper (stRegPath [iIndex]), 0);
    } 

    SetForegroundWindow (hWndRegedit);
    SetFocus (hWndRegedit);

    if (lpctValue.length())
    {
        HWND hWndListView = FindWindowEx (hWndRegedit, NULL, _T("SysListView32"), NULL);
        SetForegroundWindow (hWndListView);
        SetFocus (hWndListView);

        Sleep (100); 

        SendMessage (hWndListView, WM_KEYDOWN, VK_HOME, 0);

        String stValue = lpctValue;

        for (String::iterator it = stValue.begin (); it != stValue.end (); ++it)
        {
            SendMessage (hWndListView, WM_CHAR, toupper (*it), 0);
        } 
    } 

    return true;
}

为什么没有系统调用?你本质上是要求在这里启动一个外部程序,不明白为什么你不使用系统或相关的fork/exec类型的东西来这样做。我发现这个链接充满了大部分虚假信息,与你试图做的事情无关。您希望实际运行REGEDIT.EXE。无论您是通过系统还是通过创建一个单独的进程并启动它,您都会得到相同的结果和限制等。避免使用系统运行可以查询API以获取信息的实用程序是一件事,当您明确的目标是运行有问题的程序时,这完全是另一回事。系统调用可能有害,因为它们会创建进程。打开regedit需要创建一个进程。如果你想创建一个进程,那么创建一个进程就是任务的一部分。你必须把regedit.exe放在某个地方,这样计算机才知道你想运行regedit。然后有人可以将其更改为DeleteEverything,并将MyBankAccountDetails发送给罪犯.exe,我猜。如果数据被恶意更改,那么编写一个不会执行不同操作的程序几乎是不可能的。为什么不使用Windows API查找和更改注册表值呢?好的,假设我将使用系统我应该使用什么参数?systemregedit应该为一个正常配置的系统使用它。这是一些真正复杂的代码,实际上并不需要。错误处理不足,并且正在泄漏ShellExecuteEx返回的进程句柄。您只需将所需路径放入注册表HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\Lastkey中,然后运行Regedit并完成操作。无需手动向RegEdit窗口发送击键。