本港台开奖现场直播 j2开奖直播报码现场
当前位置: 新闻频道 > IT新闻 >

码报:使用新式 C++ 访问 Windows 注册表(4)

时间:2017-07-11 15:22来源:本港台直播 作者:本港台直播 点击:
我认为在表示多字符串原始缓冲区方面,vectorwchar_t 比 wstring 更加清楚。此外,还请注意,由于 RegGetValue API 返回的大小值以字节为单位,因此必须先将它

我认为在表示多字符串原始缓冲区方面,vector<wchar_t> 比 wstring 更加清楚。此外,还请注意,由于 RegGetValue API 返回的大小值以字节为单位,因此必须先将它正确转换成 wchar_t 计数,然后才能传递给 vector::resize 方法。

然后,可以第二次调用 RegGetValue API,在之前分配的缓冲区中写入实际的多字符串数据:

retCode = ::RegGetValue( hKey, subKey.c_str(), value.c_str(), RRF_RT_REG_MULTI_SZ, nullptr, &data[0], &dataSize);

&data[0] 自变量指向输出缓冲区的开头。

同样,必须检查 API 返回代码,并指明抛出 C++ 异常的错误条件:

if(retCode != ERROR_SUCCESS){ throwRegistryError{ "Cannot read multi-string"from registry", retCode};}

最好也使用作为输出参数由 RegGetValue API 返回的 dataSize 值适当地重设数据缓冲区的大小:

data.resize( dataSize / sizeof( wchar_t) );

此时,数据变量(即 vector<wchar_t>)存储以双 NUL 结尾的字符串序列。最后一步是,解析此数据结构,并将它转换成级别更高且更便捷的 vector<wstring>:

// Parse the double-NUL-terminated string into a vector<wstring>std::vector<std::wstring> result; constwchar_t* currStringPtr = &data[0]; while(*currStringPtr != L'0'){ // Current string is NUL-terminated, so get its length with wcslenconstsize_t currStringLength = wcslen(currStringPtr); // Add current string to result vectorresult.push_back(std::wstring{ currStringPtr, currStringLength }); // Move to the next stringcurrStringPtr += currStringLength + 1;}

最后,可以将结果 vector<wstring> 对象返回给调用方:

returnresult;

可以按下面的方式直接调用此 RegGetMultiString C++ 包装器:

vector<wstring> multiString = RegGetMultiString( HKEY_CURRENT_USER, subkey, L "MyMultiSz");

同样,Win32 RegGetValue API 的所有复杂性是被隐藏在更高级别的便捷 C++ 接口后面了。

枚举注册表项下的值

另一常见的 Windows 注册表操作是枚举给定注册表项下的值。Windows 为此提供了 RegEnumValue API (bit.ly/2jB4kaV)。在本文中,我将介绍如何使用此 API 来获取给定注册表项下值的名称和类型列表(枚举过程包装在更高级别的便捷 C++ 函数中)。自定义 C++ 函数可以将与要枚举的项相关的有效 HKEY 句柄用作输入。如果成功,此自定义 C++ 包装器函数会返回一对向量: 这对向量中的第一项是包含值名称的 wstring,第二项是表示值类型的 DWORD。所以,此 C++ 包装器函数的原型如下所示:

std::vector<std::pair<std::wstring, DWORD>> RegEnumValues(HKEY hKey)

现在,我将详细介绍枚举过程。我的想法是先调用 RegQueryInfoKey (bit.ly/2jraw2H) API 来获取一些有用的枚举前信息,如给定注册表项下的值总计数和值名称最大长度,如图 1 中所示。

图 1:调用 RegQuery­InfoKey API

DWORD valueCount{};DWORD maxValueNameLen{};LONG retCode = ::RegQueryInfoKey( hKey, nullptr, // No user-defined classnullptr, // No user-defined class sizenullptr, // Reservednullptr, // No subkey countnullptr, // No subkey max lengthnullptr, // No subkey class length&valueCount, &maxValueNameLen, nullptr, // No max value lengthnullptr, // No security deornullptr// No last write time);

请注意,我对不关注的各条信息传递的是 nullptr。当然,必须检查返回值,并在调用上述 API 出错时抛出异常:

if(retCode != ERROR_SUCCESS){ throwRegistryError{ "Cannot query key info from"the registry", retCode};}

(责任编辑:本港台直播)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
推荐内容