如何读取Registry的键值并使用MessageBox()将其打印到屏幕上

时间:2012-05-20 17:44:21

标签: c++ winapi

我是C ++和WinCe开发的新手。

我想从注册表中读取一个字符串,并显示MessageBox()。我尝试了以下内容。

HKEY key;
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\GPS Intermediate Driver\\Drivers\\SiRFStar3HW"), 0, KEY_READ, &key) != ERROR_SUCCESS)
{
    MessageBox(NULL,L"Can't open the registry!",L"Error",MB_OK);
}
char value[5];
DWORD value_length=5;
DWORD type=REG_SZ;
RegQueryValueEx(key,(LPCTSTR)"Baud", NULL, &type, (LPBYTE)&value, &value_length);
wchar_t buffer[5];
_stprintf(buffer, _T("%i"), value);

::MessageBox(NULL,buffer,L"Value:",MB_OK);

::RegCloseKey(key);

所以我知道这里有些不对劲,但我怎么解决?

5 个答案:

答案 0 :(得分:19)

导航Win32 API可能是一件棘手的事情。注册表API是一些更复杂的。这是一个简短的程序,用于演示如何读取注册表字符串。

#include <Windows.h>
#include <iostream>
#include <string>

using namespace std;

wstring ReadRegValue(HKEY root, wstring key, wstring name)
{
    HKEY hKey;
    if (RegOpenKeyEx(root, key.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
        throw "Could not open registry key";

    DWORD type;
    DWORD cbData;
    if (RegQueryValueEx(hKey, name.c_str(), NULL, &type, NULL, &cbData) != ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        throw "Could not read registry value";
    }

    if (type != REG_SZ)
    {
        RegCloseKey(hKey);
        throw "Incorrect registry value type";
    }

    wstring value(cbData/sizeof(wchar_t), L'\0');
    if (RegQueryValueEx(hKey, name.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&value[0]), &cbData) != ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        throw "Could not read registry value";
    }

    RegCloseKey(hKey);

    size_t firstNull = value.find_first_of(L'\0');
    if (firstNull != string::npos)
        value.resize(firstNull);

    return value;
}

int wmain(int argc, wchar_t* argv[])
{
    wcout << ReadRegValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", L"CommonFilesDir");
    return 0;
}

备注:

  1. 我没有CE所以这是一个简单的Win32应用程序,为Unicode编译。我采用了这条路线,因为CE不做ANSI字符。
  2. 我利用了许多C ++功能。最重要的是std::wstring。这使得字符串处理很容易。
  3. 我使用异常进行错误处理。您可以使用其他机制替换它,但它有助于我在后台保留错误处理问题。
  4. 使用异常会使关闭注册表项略显混乱。更好的解决方案是使用RAII类来包装注册表项的生命周期。为简单起见,我省略了这一点,但在生产代码中,您需要采取额外的步骤。
  5. 通常,RegQueryValueEx返回以null结尾的REG_SZ数据。此代码通过截断超出第一个空字符来处理该问题。如果返回的值不是以null结尾,则不会发生截断,但值仍然可以正常。
  6. 我刚刚打印到我的控制台,但是拨打MessageBox对你来说是微不足道的。像这样:MessageBox(0, value.c_str(), L"Caption", MB_OK)

答案 1 :(得分:2)

这是一个完整的源代码,用于读取Registry的键值并将其打印到屏幕上:

//Create C++ Win32 Project in Visual Studio
//Project -> "project" Properties->Configuration Properties->C/C++->Advanced->Show Includes : YES(/ showIncludes)
//Project -> "project" Properties->Configuration Properties->General->Project Defaults->Use of MFC : Use MFC in a shared DLL
#include <iostream>
#include <afx.h>
using namespace std;

int ReadRegistryKeyAttributes(CString ConstantKeyPath)
{
    //Here ConstantKeyPath is considered as Registry Key Path to Read
    HKEY MyRegistryKey;
    if (RegOpenKeyEx(HKEY_CURRENT_USER, ConstantKeyPath, 0, KEY_READ, &MyRegistryKey) != ERROR_SUCCESS)
    {
        cout << "KeyOpen Failed" << endl;
        return -1;
    }


    DWORD type = REG_DWORD;
    DWORD cbData;
    unsigned long size = 1024;
    CString csVersionID;

    csVersionID = _T("VersionID"); //Here VersionID is considered as Name of the Key
    if (RegQueryValueEx(MyRegistryKey, csVersionID, NULL, &type, (LPBYTE)&cbData, &size) != ERROR_SUCCESS)
    {
        RegCloseKey(MyRegistryKey);
        cout << "VersionID Key Attribute Reading Failed" << endl;
        return -1; //Error
    }
    else
    {
        cout << "VersionID = " << cbData << endl; //Key value will be printed here.
    }
    return 1; //Success
}
int main()
{
    int iResult;
    CString KeyPath = _T("Software\\RCD_Technologies\\Rajib_Test");
    iResult = ReadRegistryKeyAttributes(KeyPath);
    if (iResult < 0)
    {
        cout << "ReadRegistryKeyAttributes operation Failed" << endl;
        return -1;
    }
    cout << "<--- ReadRegistryKeyAttribute Operation Successfull -->" << endl;
    getchar();
    return 0;
}

希望这个例子对于寻找这个问题的人有用。

答案 2 :(得分:1)

这是未经测试的(我的设备没有您的密钥/值),但是为CE编译并为您提供了如何执行以下操作的要点:     #include

int _tmain(int argc, _TCHAR* argv[])
{
    HKEY key;

    if(!RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, 
        _T("System\\CurrentControlSet\\GPS Intermediate Driver\\Drivers\\SiRFStar3HW"), 
        0, 
        NULL, 
        &key))
    {
        MessageBox(NULL, _T("Failed to open key"), _T("Error"), 0);
        return -1;
    }

    DWORD length;

    // get the size - it's going to be 4 for a DWORD, but this shows how to deal with REG_SZ, etc
    if(!RegQueryValueEx(
        key, 
        _T("Baud"), 
        NULL, 
        NULL, 
        NULL, 
        &length))
    {
        MessageBox(NULL, _T("Failed to get buffer size"), _T("Error"), 0);
        goto exit;
    }

    // allocate - again, if we know it's a DWORD, this could be simplified
    BYTE *buffer = (BYTE*)LocalAlloc(LPTR, length);

    // query
    if(!RegQueryValueEx(
        key, 
        _T("Baud"), 
        NULL, NULL, 
        buffer, 
        &length))
    {
        MessageBox(NULL, _T("Failed to get value data"), _T("Error"), 0);
        goto exit;
    }

    // assuming "baud" is a DWORD, not a string
    DWORD baud = *(DWORD*)buffer;

    // build an output
    TCHAR message[MAX_PATH];
    _stprintf(message, _T("The baud value is %i"), baud);
    MessageBox(NULL, message, _T("Success"), 0);

    exit:
    RegCloseKey(key);

    return 0;
}

答案 3 :(得分:-1)

使用char数组时,您需要设置缓冲区而不是指向缓冲区的指针,如下所示:

MessageBox(0,&buffer,"Value:",MB_OK);

答案 4 :(得分:-1)

只需使用RegQueryValueEx并将其放入buf