使用 C++11 Range For-Loop 枚举注册表、文件夹和 WMI

使用 C++11 range for-loop 来枚举 Windows 注册表键/值、文件夹中的文件和 Windows Management Instrumentation (WMI) 查询,可以不需要样板初始化代码或知道底层的 Win32 API

优点

  • 资源管理由 RAII 完成:句柄和资源在Enumerator's 的析构函数中释放。
  • Windows API 使用细节是从用户那里抽象出来的。
  • 要编写的样板代码更少,只需专注于您的业务逻辑。

缺点

  • 生成的迭代器Enumerator不能在 STL 算法中使用,因为底层枚举对象不是集合。
  • 这不能应用于使用EnumWindows等异步回调完成的枚举,因为回调不能重构为 rangefor循环迭代器。

枚举文件夹示例

EnumFolder类采用原始Win32 API文件夹枚举的MSDN示例来枚举文件夹。EnumFolder实现在后面的部分中显示。

#include "EnumFolder.h"

EnumFolder enumFolder(L"c:\\temp");
for (auto const& ffd : enumFolder)
{
    if (IsFolder(ffd))
    {
        std::wcout << L"  " << ffd.cFileName << "   <DIR>\n";
    }
    else
    {
        LARGE_INTEGER filesize;
        filesize.LowPart = ffd.nFileSizeLow;
        filesize.HighPart = ffd.nFileSizeHigh;
        std::wcout << L"  " << ffd.cFileName << "   " 
            << filesize.QuadPart << L" bytes\n";
    }
}

枚举注册表项示例

与下面这个简洁示例的原始Win32注册表枚举的MSDN示例相比,开发人员无需编写那么多行样板代码。

#include "EnumRegistryKey.h"

EnumRegistryKey enumRegistryKey(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft");
for (auto const& szKey : enumRegistryKey)
{
    std::wcout << szKey << L"\n";
}

枚举注册表值示例

for这是使用 range -loop枚举注册表值的示例。

#include "EnumRegistryValue.h"

EnumRegistryValue enumRegistryValue(HKEY_CURRENT_USER, L"Software\\7-Zip\\Compression");
for (auto const& szValueName : enumRegistryValue)
{
    std::wcout << szValueName << L"\n";
}

枚举 WMI 示例

这是枚举系统中运行的进程的 WMI 查询结果的示例,其中包含 ranged for-loop。
注意:必须为 WMI 初始化和取消初始化 COM 运行时。您可以尝试更改 SQL 查询并查看它返回的结果。

#include "EnumWmi.h"

if (!InitializeCOM())
{
    std::cerr << "InitializeCOM() fails! Program exits.\n";
    return 1;
}
{
    EnumWmi enumWmi(L"SELECT * FROM Win32_Process");
    for (const auto& process : enumWmi)
    {
        _bstr_t str = process[L"Name"].bstrVal;
        std::cout << "Program name: " << str << std::endl;
    }
}
CoUninitialize();

EnumFolder 类是如何实现的

要启用 C++11 range for-loop,基本上需要编写两个类:Enumerator充当'collection'类的类和iterator迭代'collection'的类。为简单起见,EnumFolder这里只解释类,因为其他Enumerator涉及注册表和 WMI 的类需要深入了解它们的工作原理。

class CStringArrayIterator
{
public:
   CStringArrayIterator(CStringArray& collection, INT_PTR const index):
      m_index(index),
      m_collection(collection)
   {
   }

   bool operator!= (CStringArrayIterator const & other) const
   {
      return m_index != other.m_index;
   }

   CString& operator* () const
   {
      return m_collection[m_index];
   }

   CStringArrayIterator const & operator++ ()
   {
      ++m_index;
      return *this;
   }

private:
   INT_PTR        m_index;
   CStringArray&  m_collection;
};

inline CStringArrayIterator begin(CStringArray& collection)
{
   return CStringArrayIterator(collection, 0);
}

inline CStringArrayIterator end(CStringArray& collection)
{
   return CStringArrayIterator(collection, collection.GetCount());
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wouderw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值