windows 注册表get/set

博客讲述了使用JNI在Java项目中操作Windows注册表的实现过程,首先通过JNI调用C++ DLL来实现注册表的读写,然后将代码适配为Qt项目,利用Qt的宽字符处理特性进行修改,确保与QString兼容。
摘要由CSDN通过智能技术生成

JNI

在开发的项目需要操作到Windows注册表,就想起《java 核心技术》(第11版)里面有个jni示例。抄!
跑一下示例,结果跑不起来,会在java层收到一个自定义的异常,异常信息是“Open key failed”。
原因是,测试代码在setValue,打开一个空的注册表项,需要改一下代码:
老的语句:

if (RegOpenKeyEx(root, cpath, 0, KEY_WRITE, &hkey) != ERROR_SUCCESS)

新的

if (RegCreateKeyExA(root, path.c_str(), 0,nullptr, REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, nullptr,&hkey,nullptr) != ERROR_SUCCESS)

CPP

java项目,抽象做的很不错。2个类一个Win32RegKey表示一个注册表项,Win32RegKeyNameEnumeration类用来遍历Win32RegKey子项。
C语言的API写一个C的dll本来是一个很好选择,cpp面向对象可以简化dll的操作,继续抄。
Win32RegKey.h

class Win32RegKey {
public:
    Win32RegKey(HKEY root, std::string path);
    virtual ~Win32RegKey();

    std::string getStringValue(const std::string& name) const;
    std::int32_t getInt32Value(const std::string& name) const;
    BYTE * getValue(_In_ const std::string& name,_Out_ LPDWORD type,_Out_ LPDWORD size) const;
    BYTE * getValue(_In_ const std::string& name,_Out_ DWORD type,DWORD size) const;

    void setValue(const std::string& name,const std::string& value) const;
    void setValue(const std::string& name,const DWORD value) const;
    void setValue(_In_ const std::string& name,_In_ BYTE * value,_In_ DWORD size) const;
    void setValue(const std::string& name,DWORD type,const BYTE *value,DWORD size) const;

    Win32RegEnumeration* names();
private:
    Win32RegEnumeration* enumeration = nullptr;
    HKEY root;
    std::string path;
};

Win32RegEnumeration.h

class Win32RegEnumeration {
public:
    Win32RegEnumeration(HKEY root,std::string path);
    ~Win32RegEnumeration() = default;
    std::string nextElement();
    bool hasMoreElements();

private:
    void startNameEnumeration();

    HKEY root;
    std::string path;
    int index = -1;
    HKEY hkey = nullptr;
    DWORD maxsize = 0;
    DWORD count = 0;
};

具体实现和测试放github

QT

项目是qt的需要移植到qt,qt默认是宽字符的(所以上面JNI的代码API我指定了带A)。
qt的条件编译会自动调用windows带W的API。
我选择适配宽字符,更好地适配QString。
qt版本的头文件版本:
Win32RegKey.h

class Win32RegKey {
public:
    Win32RegKey(HKEY root, std::wstring path);
    virtual ~Win32RegKey();

    std::wstring getWStringValue(const std::wstring& name) const;
    std::int32_t getInt32Value(const std::wstring& name) const;
    BYTE * getValue(_In_ const std::wstring& name,_Out_ LPDWORD type,_Out_ LPDWORD size) const;
    BYTE * getValue(_In_ const std::wstring& name,_Out_ DWORD type,DWORD size) const;

    void setValue(const std::wstring& name,const std::wstring& value) const;
    void setValue(const std::wstring& name,const DWORD value) const;
    void setValue(_In_ const std::wstring& name,_In_ BYTE * value,_In_ DWORD size) const;
    void setValue(const std::wstring& name,DWORD type,const BYTE *value,DWORD size) const;

    Win32RegEnumeration* names();
private:
    Win32RegEnumeration* enumeration = nullptr;
    HKEY root;
    std::wstring path;
};

Win32RegEnumeration.h

class Win32RegEnumeration {
public:
    Win32RegEnumeration(HKEY root,std::wstring path);
    ~Win32RegEnumeration() = default;
    std::wstring nextElement();
    bool hasMoreElements();

private:
    void startNameEnumeration();

    HKEY root;
    std::wstring path;
    int index = -1;
    HKEY hkey = nullptr;
    DWORD maxsize = 0;
    DWORD count = 0;
};

实现就不贴了,需要注意的是宽字符空间处理的问题(2倍)。

void Win32RegKey::setValue(const std::wstring& name,const std::wstring& value) const {
    setValue(name,REG_SZ,reinterpret_cast<const BYTE *>(value.c_str()),(value.size()+1)<<1);
}

读取的时候

case REG_SZ: qDebug() << QString::fromWCharArray((wchar_t*)value3); break;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值