65.9K
CodeProject 正在变化。 阅读更多。
Home

Happy Registry:Win32 数据库的快速包装器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (10投票s)

2015年10月17日

CPOL

1分钟阅读

viewsIcon

17773

操作注册表的简单模板

引言

有人尝试过几次付钱让我重写整个 Win32 库。虽然我完全可以做到,但我感到非常厌倦。相反,我专注于一些真正需要的功能,为使用它们所需的代码行数感到沮丧,最终为单行操作创建了一个快速的 C++ 类。

这里是一个用于操作注册表的简单类。

构造函数、赋值运算符和析构函数

RKEY(HKEY root,const wchar_t* subkey,DWORD acc = KEY_ALL_ACCESS);
RKEY(HKEY);
RKEY(const RKEY&);
RKEY(RKEY&&);
void operator=(HKEY);
void operator=(const RKEY&);
void operator=(RKEY&&);
~RKEY();

通常的都有,允许从现有的 HKEYRKEY 进行构造,以及使用 rootsubkey 进行构造(内部创建 RegCreateKeyEx)。支持移动语义。Copy 构造函数复制密钥句柄。

使用示例

// Create a RKEY from a known path 
RKEY r(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Run");

查询或枚举值

// Get a VALUE from a RKEY
VALUE operator [](const wchar_t* v) const;

// Enum all values
vector<VALUE> EnumValues() const;

// Enum all subkeys
vector<wstring> EnumSubkeys() const;

// And the VALUE members
template <typename T> operator T() const;
operator std::wstring() const;
::name, ::value, ::ty;

RKEYOperator [] 返回一个 RKEY::VALUE,可用于操作该值。

使用示例

// Create a RKEY from a known path 
RKEY r(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Run");
string str = r["OneDrive"]; //str = "C:\...\OneDrive.exe" /background
DWORD some_dword = r["blahblah"]; // Internally gets RegQueryValueEx and 
                                  // copies the value to a DWORD
vector<wstring> subs = r.EnumSubKeys();
vector<VALUE> allvalues = r.EnumValues();

请注意,RKEY::operator [] 在执行转换之前不会查询值类型,因此您必须知道它实际上是一个 DWORD 值。如果您不知道类型,可以使用 vector<VALUE> EnumValues() 枚举值,并使用成员 name, value, ty 访问名称、类型和数据。

设置或删除值

// Get a VALUE from a RKEY
VALUE operator [](const wchar_t* v) const;

// Set 
void operator =(const wchar_t* val);
void operator =(unsigned long val);
void operator =(unsigned long long val);

// Delete 
bool DeleteSingle(const wchar_t* sub);
bool Delete(const wchar_t* sub = 0);

DeleteSingle() 删除一个 subkey,该 subkey 不应具有其他 subkeyDelete() 删除整个 subkey ,或者,如果传递了 null,则删除当前键。

使用示例

// Create a RKEY from a known path 
RKEY r(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Run");
r["OneDrive"] = L"c:\dos\format.exe c: /u /norecovery /permanent /nowarnings /destroy /lowlevel";

完整代码

    // ---------------------------------------------------------------------
    // RKEY, quick registry access 
    class RKEY
        {
        private:
            HKEY k = 0;
        public:

            class VALUE
                {
                public:
                    std::wstring name;
                    vector<char> value; // For enums
                    HKEY k = 0;
                    mutable DWORD ty = 0;

                    VALUE(const wchar_t* s,HKEY kk)
                        {
                        if (s)
                            name = s;
                        k = kk;
                        }

                    bool operator =(const wchar_t* val)
                        {
                        ty = REG_SZ;
                        return RegSetValueEx(k,name.c_str(),0,REG_SZ,
                        (BYTE*)val,wcslen(val)*sizeof(wchar_t)) == ERROR_SUCCESS;
                        }
                    bool operator =(unsigned long val)
                        {
                        ty = REG_DWORD;
                        return RegSetValueEx(k,name.c_str(),0,REG_DWORD,
                        (BYTE*)&val,sizeof(val)) == ERROR_SUCCESS;
                        }
                    bool operator =(unsigned long long val)
                        {
                        ty = REG_QWORD;
                        return RegSetValueEx(k,name.c_str(),0,REG_QWORD,
                        (BYTE*)&val,sizeof(val)) == ERROR_SUCCESS;
                        }

                    template <typename T>
                    operator T() const
                        {
                        T ch = 0;
                        RegQueryValueEx(k,name.c_str(),0,&ty,0,&ch);
                        std::vector<char> d(ch + 10);
                        ch += 10;
                        RegQueryValueEx(k,name.c_str(),0,&ty,(LPBYTE)d.data(),&ch);
                        T ret = 0;
                        memcpy(&ret,d.data(),sizeof(T));
                        return ret;
                        }

                    operator std::wstring() const
                        {
                        DWORD ch = 0;
                        RegQueryValueEx(k,name.c_str(),0,&ty,0,&ch);
                        std::vector<char> d(ch + 10);
                        ch += 10;
                        RegQueryValueEx(k,name.c_str(),0,&ty,(LPBYTE)d.data(),&ch);
                        return std::wstring((const wchar_t*)d.data());
                        }

                    bool Delete()
                        {
                        return (RegDeleteValue(k,name.c_str()) == ERROR_SUCCESS);
                        }
                };

            RKEY()
               {
               k = 0;
               }

            RKEY(HKEY kk)
                {
                k = kk;
                }

            RKEY(const RKEY& k)
                {
                operator =(k);
                }
            void operator =(const RKEY& r)
                {
                Close();
                DuplicateHandle(GetCurrentProcess(),r.k,GetCurrentProcess(),
                               (LPHANDLE)&k,0,false,DUPLICATE_SAME_ACCESS);
                }

            RKEY(RKEY&& k)
                {
                operator =(std::forward<RKEY>(k));
                }
            void operator =(RKEY&& r)
                {
                Close();
                k = r.k;
                r.k = 0;
                }

            void operator =(HKEY kk)
                {
                Close();
                k = kk;
                }

            RKEY(HKEY root,const wchar_t* subkey,DWORD acc = KEY_ALL_ACCESS)
                {
                Load(root,subkey,acc);
                }
            bool Load(HKEY root,const wchar_t* subkey,DWORD acc = KEY_ALL_ACCESS)
                {
                Close();
                return (RegCreateKeyEx(root,subkey,0,0,0,acc,0,&k,0) == ERROR_SUCCESS);
                }
            bool Open(HKEY root,const wchar_t* subkey,DWORD acc = KEY_ALL_ACCESS)
                {
                Close();
                return (RegOpenKeyEx(root,subkey,0,acc,&k) == ERROR_SUCCESS);
                }

            void Close()
                {
                if (k)
                    RegCloseKey(k);
                k = 0;
                }

            ~RKEY()
                {
                Close();
                }

            bool Valid() const
                {
                if (k) 
                    return true;
                return false;
                }

            bool DeleteSingle(const wchar_t* sub)
                {
                return (RegDeleteKey(k,sub) == ERROR_SUCCESS);
                }

            bool Delete(const wchar_t* sub = 0)
                {
                return (RegDeleteTree(k,sub) == ERROR_SUCCESS);
                }

            bool Flush()
                {
                return (RegFlushKey(k) == ERROR_SUCCESS);
                }

            vector<wstring> EnumSubkeys() const
                {
                vector<wstring> data;
                for (int i = 0;; i++)
                    {
                    vector<wchar_t> n(300);
                    DWORD sz = n.size();
                    if (RegEnumKeyEx(k,i,n.data(),&sz,0,0,0,0) != ERROR_SUCCESS)
                        break;
                    data.push_back(n.data());
                    }
                return data;
                }

            vector<VALUE> EnumValues() const
                {
                vector<VALUE> data;
                for (int i = 0;; i++)
                    {
                    vector<wchar_t> n(300);
                    DWORD sz = n.size();
                    DWORD ay = 0;
                    RegEnumValue(k,i,n.data(),&sz,0,0,0,&ay);
                    vector<char> v(ay);
                    DWORD ty = 0;
                    sz = n.size();
                    if (RegEnumValue(k,i,n.data(),&sz,0,&ty,(LPBYTE)v.data(),&ay) 
                                                                  != ERROR_SUCCESS)
                        break;
                    
                    VALUE x(n.data(),k);
                    x.ty = ty;
                    x.value = v;
                    data.push_back(x);
                    }
                return data;
                }

            VALUE operator [](const wchar_t* v) const
                {
                VALUE kv(v,k);
                return kv;
                }

            operator HKEY()
                {
                return k;
                }
        };

历史

  • 2015-10-17:首次发布
© . All rights reserved.