potisanのプログラミングメモ

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

C++20&WinAPI&WIL ZIPファイルに関連付けられたCLSIDを取得する

ZIPファイルに関連付けられたCLSIDとそのProgIDを取得するコードです。

#include <array>
#include <bit>
#include <format>
#include <string>
#include <optional>

#define STRICT
#include <windows.h>

#include "wil/resource.h"

std::optional<GUID> GetSystemFileAssociationCLSID(PCWSTR name) noexcept
{
    const auto path = std::format(L"SystemFileAssociations\\{}\\CLSID", name);
    wil::unique_hkey hkey;
    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, path.data(), 0, KEY_READ, hkey.put()) != ERROR_SUCCESS)
    {
        return std::nullopt;
    }

    DWORD keyType = 0;
    DWORD dataLen = 0;
    RegQueryValueExW(hkey.get(), L"", nullptr, &keyType, nullptr, &dataLen);
    if (keyType != REG_SZ || dataLen != 39 * sizeof(wchar_t))
    {
        return std::nullopt;
    }

    std::array<wchar_t, 39> data;
    if (RegQueryValueExW(hkey.get(), L"", nullptr, &keyType,
        std::bit_cast<PBYTE>(data.data()), &dataLen) != ERROR_SUCCESS || keyType != REG_SZ)
    {
        return std::nullopt;
    }

    GUID guid;
    if (CLSIDFromString(data.data(), &guid) != S_OK)
    {
        return std::nullopt;
    }

    return guid;
}

wil::unique_cotaskmem_string ProgIDFromCLSID(REFCLSID clsid)
{
    wil::unique_cotaskmem_string progId;
    THROW_IF_FAILED(ProgIDFromCLSID(clsid, progId.put()));
    return progId;
}

int main()
{
    auto clsid = GetSystemFileAssociationCLSID(L".zip");
    if (!clsid) return 0;

    auto progId = ProgIDFromCLSID(*clsid);

    return 0;
}

参考