potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C++&WIL Windowsプロパティシステムのプロパティ情報を列挙する

C++20とWILでWindowsプロパティシステムのプロパティ情報を列挙するサンプルコードです。コードの変更でプロパティの他の情報も列挙できます。

コード

#include <iostream>
#include <string>

#pragma comment(lib, "propsys.lib")
#define STRICT
#include <Windows.h>
#include <propsys.h>

#include <wil/com.h>
#include <wil/resource.h>

// PSGetPropertySystem関数のラッパーです。
wil::com_ptr<IPropertySystem> PSGetPropertySystem()
{
    wil::com_ptr<IPropertySystem> propSys;
    THROW_IF_FAILED(PSGetPropertySystem(IID_PPV_ARGS(&propSys)));
    return std::move(propSys);
}

std::wstring PropDescDisplayTypeToString(PROPDESC_DISPLAYTYPE type)
{
    switch (type)
    {
    case PDDT_STRING: return L"文字列";
    case PDDT_NUMBER: return L"数値";
    case PDDT_BOOLEAN: return L"論理型";
    case PDDT_DATETIME: return L"日付";
    case PDDT_ENUMERATED: return L"列挙型";
    default: return L"(不明)";
    }
}

int main()
{
    auto path = LR"(C:\Windows)";

    std::wcout.imbue(std::locale("japanese", std::locale::ctype));

    auto couninit = wil::CoInitializeEx(COINIT_APARTMENTTHREADED);

    auto propSystem = PSGetPropertySystem();
    wil::com_ptr<IPropertyDescriptionList> descList;
    THROW_IF_FAILED(propSystem->EnumeratePropertyDescriptions(
        PDEF_ALL, IID_PPV_ARGS(&descList)));
    UINT count;
    THROW_IF_FAILED(descList->GetCount(&count));
    for (UINT i = 0; i < count; i++)
    {
        wil::com_ptr<IPropertyDescription> desc;
        THROW_IF_FAILED(descList->GetAt(i, IID_PPV_ARGS(&desc)));

        PROPERTYKEY key;
        wil::unique_cotaskmem_string keyFmtid;
        std::wstring keyPid;
        wil::unique_cotaskmem_string canonicalName;
        wil::unique_cotaskmem_string displayName;
        PROPDESC_DISPLAYTYPE dispType;
        desc->GetPropertyKey(&key);
        StringFromCLSID(key.fmtid, &keyFmtid);
        keyPid = std::to_wstring(key.pid);
        desc->GetCanonicalName(&canonicalName);
        desc->GetDisplayName(&displayName);
        desc->GetDisplayType(&dispType);

        std::wcout
            << "(" << wil::string_get_not_null(keyFmtid) << L", " << keyPid << L"), "
            << wil::string_get_not_null(canonicalName) << L", "
            << wil::string_get_not_null(displayName) << L", "
            << PropDescDisplayTypeToString(dispType) << std::endl;
    }

    return 0;
}

出力例

({B725F130-47EF-101A-A5F1-02608C9EEBAC}, 16), System.DateAccessed, アクセス日時, 日付
({B725F130-47EF-101A-A5F1-02608C9EEBAC}, 15), System.DateCreated, 作成日時, 日付
({B725F130-47EF-101A-A5F1-02608C9EEBAC}, 14), System.DateModified, 更新日時, 日付
({B725F130-47EF-101A-A5F1-02608C9EEBAC}, 13), System.FileAttributes, 属性, 数値
({8D72ACA1-0716-419A-9AC1-ACB07B18DC32}, 2), System.FileAttributesDisplay, , 文字列
({0CEF7D53-FA64-11D1-A203-0000F81FEDEE}, 3), System.FileDescription, ファイルの説明, 文字列
({E4F10A3C-49E6-405D-8288-A23BD4EEAA6C}, 100), System.FileExtension, ファイル拡張子, 文字列
({41CF5AE0-F75A-4806-BD87-59C7D9248EB9}, 100), System.FileName, ファイル名, 文字列
({9B174B34-40FF-11D2-A27E-00C04FC30871}, 4), System.FileOwner, 所有者, 文字列
({FCEFF153-E839-4CF3-A9E7-EA22832094B8}, 101), System.FolderKind, , 文字列
({B725F130-47EF-101A-A5F1-02608C9EEBAC}, 25), System.FolderNameDisplay, , 文字列