导航:[首页]->[windows]->[注册表工具函数备份]
#include <Windows.h>
#include <tchar.h>
#include <string>
#include <Shlwapi.h>
#include <cassert>

#if defined _UNICODE || defined UNICODE
typedef std::wstring String;
#else
typedef std::string String;
#endif

#pragma comment(lib,"Shlwapi.lib")

class Reg
{
public:
    Reg() : m_handle_(NULL){}
    ~Reg(){ this->Close(); }

    // Open/Close
    /*
    HKEY_CLASSES_ROOT
    HKEY_CURRENT_CONFIG
    HKEY_CURRENT_USER
    HKEY_LOCAL_MACHINE
    HKEY_USERS
    */
    inline bool Open(HKEY hKey, const String& path)
    {
        return OpenImp(hKey, path, KEY_READ);
    }
    inline bool OpenWrite(HKEY hKey, const String& path)
    {
        return OpenImp(hKey, path, KEY_WRITE);
    }
    inline bool OpenReadWrite(HKEY hKey, const String& path)
    {
        return OpenImp(hKey, path, KEY_READ | KEY_WRITE);
    }
    inline void Close()
    {
        if (m_handle_)
        {
            RegCloseKey(m_handle_);
            m_handle_ = NULL;
        }
    }

    // CreateDir/DeleteDir
    inline bool CreateDir(const String& path)
    {
        HKEY hKey_;
        LONG ret_ = RegCreateKey(m_handle_,
            path.c_str(),
            &hKey_);
        if (!ret_)
        {
            RegCloseKey(hKey_);
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("CreateDir"), ret_);
        return false;
    }
    inline bool DeleteDir(const String& path)
    {
#if 0
        LONG ret_ = RegDeleteKey(m_handle_, path.c_str());
        if (!ret_)
        {
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("DeleteDir"), ret_);
        return false;
#else
        LSTATUS ret_ = SHDeleteKey(m_handle_, path.c_str());
        if (ret_ == ERROR_SUCCESS)
        {
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("SHDeleteKey"), ret_);
        return false;
#endif
    }
    bool CopyDir(const String& str, Reg& reg)
    {
        LSTATUS ret_ = SHCopyKey(m_handle_,
            str.c_str(),
            reg.m_handle_,
            0);
        if (ret_ == ERROR_SUCCESS)
        {
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("SHCopyKey"), ret_);
        return false;
    }
    bool StatDir(DWORD* dircnt,DWORD* filecnt,
        DWORD* dirmaxlen, DWORD* filemaxlen)
    {
        DWORD dircnt_ = 0, filecnt_ = 0;
        DWORD dirmaxlen_ = 0, filemaxlen_ = 0;
        LSTATUS ret_ = RegQueryInfoKey(
            m_handle_,
            NULL, NULL, NULL,
            &dircnt_,
            &dirmaxlen_, 
            NULL,
            &filecnt_,
            &filemaxlen_,
            NULL, NULL, NULL);
        if( ret_ == ERROR_SUCCESS)
        {
            if (dircnt) *dircnt = dircnt_;
            if (filecnt) *filecnt = filecnt_;
            if (dirmaxlen) *dirmaxlen = dirmaxlen_;
            if (filemaxlen) *filemaxlen = filemaxlen_;
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("RegQueryInfoKey"), ret_);
        return false;
    }
    bool GetSubDir(DWORD index,DWORD len,String* str)
    {
        assert(str);
        TCHAR* buf_ = new TCHAR[len + 1];
        LONG ret_ = RegEnumKey(
            this->m_handle_,
            index,
            buf_,
            (len + 1)*sizeof(TCHAR));
        if (!ret_)
        {
            *str = buf_;
            delete[] buf_;
            return true;
        }
        delete[] buf_;
        assert(ret_ != ERROR_MORE_DATA);
        _tprintf(_T("[%s] error [%u]\n"), _T("RegEnumKey"), ret_);
        return false;
    }
    bool GetSubFile(DWORD index, DWORD len, String* str,DWORD* type)
    {
        assert(str && type);
        DWORD len_ = (len + 1)*sizeof(TCHAR);
        TCHAR* buf_ = new TCHAR[len + 1];
        LONG ret_ = RegEnumValue(
            this->m_handle_,
            index,
            buf_,
            &len_,
            0,
            type,
            NULL,
            NULL);
        if (!ret_)
        {
            *str = buf_;
            delete[] buf_;
            return true;
        }
        delete[] buf_;
        assert(ret_ != ERROR_MORE_DATA);
        _tprintf(_T("[%s] error [%u]\n"), _T("RegEnumKey"), ret_);
        return false;
    }

    // pwd/cd
    inline const String& Pwd() const
    {
        return this->m_path_;
    }
    bool Goto(const String& path)
    {
        if (String::npos != path.find(_T('\\')))
        {
            _tprintf(_T("[%s] error path %s\n"), _T("Goto"),path.c_str());
            return false;
        }
        HKEY hKey_;
        LONG ret_ = RegOpenKeyEx(
            m_handle_,
            path.c_str(),
            0,
            this->m_desired_,
            &hKey_);
        if (!ret_)
        {
            this->Close();
            this->m_handle_ = hKey_;
            if (this->m_path_[this->m_path_.length() - 1] != _T('\\'))
            {
                this->m_path_ += _T('\\');
            }
            this->m_path_ += path;
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("RegOpenKeyEx"), ret_);
        return false;
    }
    bool GotoParent()
    {
        size_t pos_ = this->m_path_.rfind(_T('\\'));
        if (pos_ == String::npos)
        {
            _tprintf(_T("[%s] error path %s\n"), 
                _T("GotoParent"),
                m_path_.c_str());
            return false;
        }
        String newpath_ = m_path_.substr(0, pos_);
        return OpenImp(m_root_, newpath_, m_desired_);
    }

    // create/edit
    bool Write(const String& key, DWORD value)
    {
        LONG ret_ = RegSetValueEx(
            this->m_handle_,
            key.c_str(),
            0,
            REG_DWORD,
            (const BYTE*)&value,
            sizeof(value));
        if (!ret_)
        {
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("RegSetValue"), ret_);
        return false;
    }
    bool Write(const String& key, const String& str)
    {
        LONG ret_ = RegSetValueEx(
            this->m_handle_,
            key.c_str(),
            0,
            REG_SZ,
            (const BYTE*)str.c_str(),
            (str.size() + 1)*sizeof(TCHAR));
        if (!ret_)
        {
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("RegSetValue"), ret_);
        return false;
    }
    bool Read(const String& key, DWORD* value)
    {
        assert(value);
        DWORD type_ = 0;
        DWORD len_ = sizeof(*value);
        LONG ret_ = RegQueryValueEx(
            this->m_handle_,
            key.c_str(),
            0,
            &type_,
            (LPBYTE)value,
            &len_);
        if (!ret_ && len_ == sizeof(*value) && type_ == REG_DWORD)
        {
            return true;
        }
        _tprintf(_T("[%s] error [%u|%u|%u]\n"), 
            _T("RegQueryValueEx"), ret_,len_,type_);
        return false;
    }
    bool Read(const String& key, String* value)
    {
        assert(value);
        DWORD type_ = 0;
        DWORD len_ = 0;
        LONG ret_ = RegQueryValueEx(
            this->m_handle_,
            key.c_str(),
            0,
            &type_,
            NULL,
            &len_);
        if (!ret_ && type_ == REG_SZ)
        {
            assert(len_%sizeof(TCHAR) == 0);
            TCHAR* ptr_ = new TCHAR[len_ / sizeof(TCHAR)];
            ret_ = RegQueryValueEx(
                this->m_handle_,
                key.c_str(),
                0,
                &type_,
                (LPBYTE)ptr_,
                &len_);
            if (!ret_)
            {
                *value = ptr_;
                delete[] ptr_;
                return true;
            }
            delete[] ptr_;
        }
        _tprintf(_T("[%s] error [%u|%u|%u]\n"),
            _T("RegQueryValueEx"), ret_, len_, type_);
        return false;
    }
    bool Stat(const String& key,DWORD* type,DWORD* len)
    {
        assert(type && len);
        LONG ret_ = RegQueryValueEx(
            this->m_handle_,
            key.c_str(),
            0,
            type,
            NULL,
            len);
        if (!ret_)
        {
            return true;
        }
        _tprintf(_T("[%s] error [%u|%u|%u]\n"),
            _T("RegQueryValueEx"), ret_, *len, *type);
        return false;
    }
    // delete
    bool Delete(const String& key)
    {
        size_t pos_ = key.rfind(_T('\\'));
        if (pos_ != String::npos)
        {
            _tprintf(_T("[%s] error path %s\n"),
                _T("Delete"),
                m_path_.c_str());
            return false;
        }
        LONG ret_ = RegDeleteValue(
            this->m_handle_,
            key.c_str());
        if (!ret_)
        {
            return true;
        }
        _tprintf(_T("[%s] error [%u]\n"), _T("RegDeleteKey"), ret_);
        return false;
    }
private:
    bool OpenImp(HKEY hKey, const String& path, REGSAM desired)
    {
        LONG ret_ = RegOpenKeyEx(
            hKey,
            path.c_str(),
            0,
            desired,
            &m_handle_);
        if (!ret_)
        {
            this->m_path_ = path;
            this->m_desired_ = desired;
            this->m_root_ = hKey;
            return true;
        }
        m_handle_ = NULL;
        _tprintf(_T("[%s] error [%u]\n"), _T("RegOpenKeyEx"), ret_);
        return false;
    }
private:
    HKEY m_root_;
    HKEY m_handle_;
    REGSAM m_desired_;
    String m_path_;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Reg reg_;
    if (!reg_.OpenReadWrite(HKEY_CURRENT_USER, _T("Software\\Tiled")))
        return -1;
    assert(reg_.CreateDir(_T("fuck")));
    _tprintf(_T("[%s] [%s]\n"), _T("PWD"), reg_.Pwd().c_str());

    assert(reg_.Write(_T("fuck"), 1234));
    assert(reg_.Goto(_T("fuck")));
    assert(reg_.Write(_T("fuck"), 12345));
    assert(reg_.Write(_T("fuck"), 123456));
    DWORD ret_;
    assert(reg_.Read(_T("fuck"), &ret_));
    _tprintf(_T("Read [%u]\n"), ret_);
    assert(reg_.Write(_T("str"), _T("FUCK")));
    String str_;
    assert(reg_.Read(_T("str"), &str_));
    _tprintf(_T("[%s] [%s]\n"), _T("Read"), str_.c_str());
    assert(reg_.Delete(_T("fuck")));
    assert(reg_.Delete(_T("str")));
    assert(reg_.GotoParent());
    assert(reg_.Delete(_T("fuck")));
    _tprintf(_T("[%s] [%s]\n"), _T("PWD"), reg_.Pwd().c_str());
    assert(reg_.DeleteDir(_T("fuck")));

    Reg reg2_;
    if (!reg2_.OpenReadWrite(HKEY_CURRENT_USER, _T("Software\\Thunder Network")))
        return -1;
    assert(reg_.CreateDir(_T("fuck\\fuck1")));
    assert(reg_.Goto(_T("fuck")));
    assert(reg_.Goto(_T("fuck1")));
    assert(reg_.Write(_T("str"), _T("FUCK")));
    assert(reg_.Write(_T("fuck"), 123456));
    assert(reg_.GotoParent());
    assert(reg_.GotoParent());
    assert(reg_.CopyDir(_T("fuck"), reg2_));
    assert(reg_.DeleteDir(_T("fuck")));
    DWORD dircnt_, filecnt_, dirmaxlen_, filemaxlen_;
    assert(reg2_.StatDir(&dircnt_, &filecnt_, &dirmaxlen_, &filemaxlen_));
    for (DWORD i = 0; i < dircnt_; i++)
    {
        String dirname_;
        assert(reg2_.GetSubDir(i, dirmaxlen_, &dirname_));
        _tprintf(_T("dirname %s\n"), dirname_.c_str());
    }
    for (DWORD i = 0; i < filecnt_; i++)
    {
        String filename_;
        DWORD type_;
        assert(reg2_.GetSubFile(i, filemaxlen_, &filename_, &type_));
        _tprintf(_T("filename %s %d\n"), filename_.c_str(),type_);
    }
    assert(reg2_.DeleteDir(_T("fuck1")));
    return 0;
}