配置文件API

前言
配置文件API包括注册表API和iniAPI.
iniAPI中有读写结构的API, 挺方便.
注册表遍历时, 加入遍历回调函数, 可以方便的实现注册表遍历打印或注册表键的遍历删除
@todo 注册表操作时需要的cbSize, 还没验证, 先按bytes算的. 在unicode下可能有问题,到时再修正.
测试工程

// testIniFileOpt.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <assert.h>
#include "testIniFileOpt.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

typedef struct _tag_RegInfo {
    TCHAR szClass[MAXBYTE]; ///< address of buffer for class string
    DWORD cbClass; ///< address of size of class string buffer 
    DWORD cbSubKeys; ///< address of buffer for number of subkeys
    DWORD cbMaxSubKeyLen; ///< address of buffer for longest subkey name length
    DWORD cbMaxClassLen; ///< address of buffer for longest class string length
    DWORD cbValues; ///< address of buffer for number of value entries
    DWORD cbMaxValueNameLen; ///< address of buffer for longest value name length
    DWORD cbMaxValueLen; ///< address of buffer for longest value data length
    DWORD cbSecurityDescriptor; ///< address of buffer for security descriptor length
    FILETIME ftLastWriteTime; ///< address of buffer for last write time

    void clear() {
        ::ZeroMemory(this, sizeof(_tag_RegInfo));
        cbClass = sizeof(szClass);
    }
}TAG_REGINFO;

typedef struct _tag_RegKeyInfo {
    TCHAR szName[MAXBYTE];     // address of buffer for subkey name
    DWORD cbName;  // address for size of subkey buffer
    TCHAR szClass[MAXBYTE];     // address of buffer for class string
    DWORD cbClass;  // address for size of class buffer
    FILETIME ftLastWriteTime; // address for time key last written to

    void clear() {
        ::ZeroMemory(this, sizeof(_tag_RegKeyInfo));
        cbName = sizeof(szName);
        cbClass = sizeof(szClass);
    }
}TAG_REGKEYINFO;

/
// The one and only application object
CWinApp theApp;

using namespace std;

void fnTestIniFileOpt_public();
void fnTestIniFileOpt_private();
void fnTestRegister();
void fnTraverseRegister();

typedef void (*PFUN_RegValueEnumProc)(HKEY hKey, TCHAR* pName);
void fnTraverseRegisterByKey(HKEY hKeyNow, 
                             PFUN_RegValueEnumProc ProcKey, 
                             PFUN_RegValueEnumProc ProcValue);

void RegValueEnumProc_PrintSubKey(HKEY hKey, TCHAR* pSubKeyName);
void RegValueEnumProc_PrintValue(HKEY hKey, TCHAR* pValueName);

void RegValueEnumProc_DelSubKey(HKEY hKey, TCHAR* pSubKeyName);
void RegValueEnumProc_DelValue(HKEY hKey, TCHAR* pValueName);

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        cerr << _T("Fatal Error: MFC initialization failed") << endl;
        nRetCode = 1;
    }
    else
    {
        // TODO: code your application's behavior here.
        CString strHello;
        strHello.LoadString(IDS_HELLO);
        cout << (LPCTSTR)strHello << endl;

        fnTestRegister();
        fnTraverseRegister();
    }

    return nRetCode;
}

void fnTraverseRegister() {
    /// 遍历注册表
    LONG lRc = 0;
    HKEY hKeyNow = NULL;

    do {
        lRc = RegOpenKeyEx(
            HKEY_CURRENT_CONFIG,
            TEXT("SOFTWARE\\MyRegisterTest"),
            0,
            KEY_ALL_ACCESS,
            &hKeyNow);
        if (!((ERROR_SUCCESS == lRc) && (NULL != hKeyNow))) {
            break;
        }

        fnTraverseRegisterByKey(hKeyNow, 
            RegValueEnumProc_DelSubKey, RegValueEnumProc_DelValue);
        RegCloseKey(hKeyNow);
        lRc = RegDeleteKey(HKEY_CURRENT_CONFIG, TEXT("SOFTWARE\\MyRegisterTest"));
        assert(ERROR_SUCCESS == lRc);
    } while (0);
}

void RegValueEnumProc_DelSubKey(HKEY hKey, TCHAR* pSubKeyName) {
    LONG lRc = 0;
    if ((NULL != hKey) && (NULL != pSubKeyName)) {
        if (_tcslen(pSubKeyName) > 0) { ///< 不删除空名字的键
            lRc = RegDeleteKey(hKey, pSubKeyName);    
            assert(ERROR_SUCCESS == lRc);
        }
    }
}

void RegValueEnumProc_DelValue(HKEY hKey, TCHAR* pValueName) {
    LONG lRc = 0;
    if ((NULL != hKey) && (NULL != pValueName)) {
        if (_tcslen(pValueName) > 0) { ///< 不删除默认值
            lRc = RegDeleteValue(hKey, pValueName);
            assert(ERROR_SUCCESS == lRc);
        }
    }
}

void RegValueEnumProc_PrintSubKey(HKEY hKey, TCHAR* pSubKeyName) {
    if ((NULL != hKey) && (NULL != pSubKeyName)) {
        TRACE("hKey[0x%p], SubKeyName[%s]\n", hKey, pSubKeyName);
    }
}

void RegValueEnumProc_PrintValue(HKEY hKey, TCHAR* pValueName) {
    if ((NULL != hKey) && (NULL != pValueName)) {
        TRACE("hKey[0x%p], ValueName[%s]\n", hKey, pValueName);
    }
}

void fnTraverseRegisterByKey(HKEY hKeyNow, 
                             PFUN_RegValueEnumProc ProcKey, 
                             PFUN_RegValueEnumProc ProcValue) {
    LONG lRc = 0;
    TAG_REGINFO RegInfo;
    DWORD dwIndex = 0;
    HKEY hSubKey = NULL;
    TAG_REGKEYINFO RegKeyInfo;

    TCHAR szValueName[MAXBYTE];
    DWORD cbValueName;

    RegInfo.clear();
    lRc = RegQueryInfoKey(
        hKeyNow,
        RegInfo.szClass,
        &RegInfo.cbClass,
        NULL, 
        &RegInfo.cbSubKeys,
        &RegInfo.cbMaxSubKeyLen,
        &RegInfo.cbMaxClassLen,
        &RegInfo.cbValues,
        &RegInfo.cbMaxValueNameLen,
        &RegInfo.cbMaxValueLen,
        &RegInfo.cbSecurityDescriptor,
        &RegInfo.ftLastWriteTime);
    if (ERROR_SUCCESS == lRc) {
        /// Traverse subKey
        for (dwIndex = (RegInfo.cbSubKeys - 1); dwIndex != (DWORD)(-1) ; dwIndex--) {
            RegKeyInfo.clear();
            lRc = RegEnumKeyEx(
                hKeyNow,
                dwIndex,
                RegKeyInfo.szName,
                &RegKeyInfo.cbName,
                NULL,
                RegKeyInfo.szClass,
                &RegKeyInfo.cbClass,
                &RegKeyInfo.ftLastWriteTime);
            if (ERROR_SUCCESS == lRc) {
                lRc = RegOpenKeyEx(
                    hKeyNow,
                    RegKeyInfo.szName,
                    0,
                    KEY_ALL_ACCESS,
                    &hSubKey);
                if ((ERROR_SUCCESS == lRc) && (NULL != hSubKey)) {
                    fnTraverseRegisterByKey(hSubKey, ProcKey, ProcValue);
                    RegCloseKey(hSubKey);
                    if (NULL != ProcKey) {
                        ProcKey(hKeyNow, RegKeyInfo.szName);
                    }
                }
            }
        }

        /// Traverse subValue
        for (dwIndex = (RegInfo.cbValues - 1); dwIndex != (DWORD)(-1) ; dwIndex--) {
            ZeroMemory(szValueName, sizeof(szValueName));
            cbValueName = sizeof(szValueName);
            lRc = RegEnumValue(
                hKeyNow,
                dwIndex,
                szValueName,
                &cbValueName,
                NULL,
                NULL,
                NULL,
                NULL);
            if (ERROR_SUCCESS == lRc) {
                if (NULL != ProcValue) {
                    ProcValue(hKeyNow, szValueName);
                }
            }
        }
    }
}

void fnTestRegister() {
    LONG lRc = 0;
    HKEY hKeyNow = NULL;
    DWORD dwDisposition = 0;
    DWORD dwType = 0;
    DWORD cbData = 0;
    TCHAR cBuf[MAX_PATH] = {TEXT('\0')};
    // HKEY_CURRENT_CONFIG\SOFTWARE

    /// 注册表API, 优先使用带Ex的API. 不带Ex的API, M$不推荐使用
    /// 是否M$不推荐使用, 请参考
    /// An application cannot create a key under HKEY_USERS or HKEY_LOCAL_MACHINE. 
    lRc = RegCreateKeyEx(
        HKEY_CURRENT_CONFIG,
        TEXT("SOFTWARE\\MyRegisterTest"),
        0,
        NULL,
        REG_OPTION_VOLATILE,
        KEY_ALL_ACCESS,
        NULL,
        &hKeyNow,
        &dwDisposition);
    assert(ERROR_SUCCESS == lRc);
    if (NULL != hKeyNow) {
        /// 写默认值内容
        _tcscpy(cBuf, TEXT("default content"));
        lRc = RegSetValueEx(
            hKeyNow,
            TEXT(""),
            0,
            REG_SZ,
            (CONST BYTE *)cBuf,
            _tcslen(cBuf) + 1);
        assert(ERROR_SUCCESS == lRc);

        /// 写指定值内容
        _tcscpy(cBuf, TEXT("MyValue1's content"));
        lRc = RegSetValueEx(
            hKeyNow,
            TEXT("MyValue1"),
            0,
            REG_SZ,
            (CONST BYTE *)cBuf,
            _tcslen(cBuf) + 1);
        assert(ERROR_SUCCESS == lRc);

        RegCloseKey(hKeyNow);
        if (REG_CREATED_NEW_KEY == dwDisposition) {
            TRACE(TEXT("REG_CREATED_NEW_KEY\n"));
        } else if (REG_OPENED_EXISTING_KEY == dwDisposition) {
            TRACE(TEXT("REG_OPENED_EXISTING_KEY\n"));
        }
    }

    lRc = RegCreateKeyEx(
        HKEY_CURRENT_CONFIG,
        TEXT("SOFTWARE\\MyRegisterTest\\SubKey1"),
        0,
        NULL,
        REG_OPTION_VOLATILE,
        KEY_ALL_ACCESS,
        NULL,
        &hKeyNow,
        &dwDisposition);
    if ((ERROR_SUCCESS == lRc) && (NULL != hKeyNow)) {
        RegCloseKey(hKeyNow);
    }

    lRc = RegCreateKeyEx(
        HKEY_CURRENT_CONFIG,
        TEXT("SOFTWARE\\MyRegisterTest\\SubKey2"),
        0,
        NULL,
        REG_OPTION_VOLATILE,
        KEY_ALL_ACCESS,
        NULL,
        &hKeyNow,
        &dwDisposition);
    if ((ERROR_SUCCESS == lRc) && (NULL != hKeyNow)) {
        RegCloseKey(hKeyNow);
    }

    /// 打开键, 读键值
    hKeyNow = NULL;
    lRc = RegOpenKeyEx(
        HKEY_CURRENT_CONFIG,
        TEXT("SOFTWARE\\MyRegisterTest"),
        0,
        KEY_ALL_ACCESS,
        &hKeyNow);
    if ((ERROR_SUCCESS == lRc) && (NULL != hKeyNow)) {
        cbData = sizeof(cBuf);
        lRc = RegQueryValueEx(
            hKeyNow,
            TEXT("MyValue1"),
            NULL,
            &dwType,
            (UCHAR*)cBuf,
            &cbData);
        if (ERROR_SUCCESS == lRc) {
            assert(REG_SZ == dwType);
            TRACE(TEXT("%s\n"), cBuf);
        }

        RegCloseKey(hKeyNow);
    }
}

#define INI_FILE_NAME TEXT("MyIniFileName.ini")
#define INI_APP_NAME TEXT("MyAppName")
#define INI_KEY_NAME TEXT("MyKeyName")
#define INI_KEY_NAME1 TEXT("MyKeyName1")

void fnTestIniFileOpt_private() {
    BOOL bRc = FALSE;
    DWORD dwRc = 0;
    TCHAR cIniPathName[MAX_PATH] = {TEXT('\0')};
    TCHAR cBuf[MAXSHORT] = {TEXT('\0')};
    TCHAR* pTmp = NULL;

    // GetCurrentDirectory 会被API改掉, 不太好
    // 还是调用GetModuleFileName
    // 如果是在DLL中, ModuleFileName让调用者传进来
    dwRc = GetModuleFileName(NULL, cIniPathName, 
        sizeof(cIniPathName) / sizeof(TCHAR));
    assert(dwRc > 0);
    pTmp = _tcsrchr(cIniPathName, TEXT('\\'));
    assert(NULL != pTmp);
    *(pTmp + 1) = TEXT('\0');
    _tcscat(cIniPathName, INI_FILE_NAME);

    // WritePrivateProfileSection 没大用
    bRc = WritePrivateProfileSection(
        INI_APP_NAME,
        INI_KEY_NAME,
        cIniPathName);
    assert(bRc);

    bRc = WritePrivateProfileString(
        INI_APP_NAME,
        INI_KEY_NAME,
        TEXT("Value1"),
        cIniPathName);
    assert(bRc);

    dwRc = GetPrivateProfileString(
        INI_APP_NAME,
        INI_KEY_NAME,
        TEXT("not found"),
        cBuf,
        sizeof(cBuf) / sizeof(TCHAR),
        cIniPathName);
    assert(dwRc > 0);
    assert(0 != strcmp(cBuf, TEXT("not found")));

    /// ini结构读写API, 方便
    /// 存贮格式未知, 如果要做校验, 自己整个算法写入校验和
    RECT rt;
    ::SetRect(&rt, 10, 20, 30, 40);

    bRc = WritePrivateProfileStruct(
        INI_APP_NAME,
        INI_KEY_NAME,
        &rt,
        sizeof(rt),
        cIniPathName);
    assert(bRc);

    ::SetRect(&rt, 0, 0, 0, 0);
    bRc = GetPrivateProfileStruct(
        INI_APP_NAME,
        INI_KEY_NAME,
        &rt,
        sizeof(rt),
        cIniPathName);
    assert(bRc);
    assert(rt.left == 10);
    assert(rt.top == 20);
    assert(rt.right == 30);
    assert(rt.bottom == 40);
}

void fnTestIniFileOpt_public() {
    BOOL bRc = FALSE;
    DWORD dwRc = 0;
    TCHAR cBuf[MAX_PATH] = {TEXT('\0')};

    // WriteProfileSection没大用, 可以被WriteProfileString代替
    // WriteProfileString 是向 $OSIDR/win.ini中写内容, 不推荐
//    bRc = WriteProfileString(INI_APP_NAME, INI_KEY_NAME, TEXT("MyKeyValue"));
//    assert(bRc);

    bRc = WriteProfileString(INI_APP_NAME, INI_KEY_NAME1, TEXT("MyKeyValue1"));
    assert(bRc);

    dwRc = GetProfileSection(INI_APP_NAME, cBuf, sizeof(cBuf) / sizeof(TCHAR));
    assert(dwRc > 0); ///< dwRc > 0, 说明INI_APP_NAME扇区下有内容, 没大用

    dwRc = GetProfileString(INI_APP_NAME, INI_KEY_NAME1, TEXT("not found"), 
        cBuf, sizeof(cBuf) / sizeof(TCHAR));

    assert(dwRc > 0);
    assert(0 != _tcscmp(cBuf, TEXT("not found")));
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值