8

我是 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);

所以我知道这里有问题,但我该如何解决?

4

5 回答 5

22

导航 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返回REG_SZ以空值结尾的数据。此代码通过截断第一个空字符之外的内容来处理该问题。如果返回的值不是以 null 结尾的,则不会发生截断,但该值仍然可以。
  6. 我刚刚打印到我的控制台,但你调用MessageBox. 像这样:MessageBox(0, value.c_str(), L"Caption", MB_OK)
于 2012-05-20T19:42:43.277 回答
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;
}

希望这个例子对寻求这个问题的人有所帮助。

于 2015-07-07T20:09:56.913 回答
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;
}
于 2012-05-20T22:55:44.513 回答
-1

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

MessageBox(0,&buffer,"Value:",MB_OK);
于 2012-05-20T19:08:42.560 回答
-1

只需使用 RegQueryValueEx 并将其放入 buf

于 2013-07-18T12:34:08.927 回答