You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C++获取文件详情标签的全部扩展属性?

在C++中获取文件详情标签的所有属性及值

当然可以!你提到的GetFileAttributes()、GetFileAttributesEx()以及WIN32_FIND_DATA这些API,只能获取文件系统层面的基础属性(比如只读、压缩、创建时间、文件大小),但文件详情标签里的大部分属性(比如文档作者、音乐流派、图片分辨率、视频时长这类)属于Windows Shell范畴的属性,需要用到Shell相关的COM API来获取。

核心思路:使用Shell的IShellItem2和IPropertyStore接口

Windows Shell提供了专门的属性系统来管理这些扩展属性,核心是IShellItem2接口(用于获取单个属性)和IPropertyStore接口(用于枚举所有属性)。

代码示例:获取指定文件的多个Shell属性

以下是一个完整的示例,展示如何获取文件的常见详情属性:

#include <windows.h>
#include <shobjidl.h>
#include <propsys.h>
#include <propkey.h>
#include <iostream>
#include <string>

#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "propsys.lib")

void PrintPropertyValue(IShellItem2* pItem, REFPROPERTYKEY propKey) {
    PROPVARIANT propVar;
    PropVariantInit(&propVar);

    if (SUCCEEDED(pItem->GetProperty(propKey, &propVar))) {
        // 根据属性类型处理值
        switch (propVar.vt) {
            case VT_LPWSTR:
                std::wcout << L"Value: " << propVar.pwszVal << std::endl;
                break;
            case VT_FILETIME: {
                SYSTEMTIME st;
                FileTimeToSystemTime(&propVar.filetime, &st);
                std::wcout << L"Value: " << st.wYear << L"/" << st.wMonth << L"/" << st.wDay 
                          << L" " << st.wHour << L":" << st.wMinute << std::endl;
                break;
            }
            case VT_UI4:
                std::wcout << L"Value: " << propVar.uiVal << std::endl;
                break;
            case VT_BOOL:
                std::wcout << L"Value: " << (propVar.boolVal ? L"True" : L"False") << std::endl;
                break;
            default:
                std::wcout << L"Unsupported property type: " << propVar.vt << std::endl;
                break;
        }
        PropVariantClear(&propVar);
    } else {
        std::wcout << L"Failed to get property value" << std::endl;
    }
}

int wmain(int argc, wchar_t* argv[]) {
    if (argc != 2) {
        std::wcout << L"Usage: " << argv[0] << L" <file path>" << std::endl;
        return 1;
    }

    // 初始化COM
    HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
    if (FAILED(hr)) {
        std::wcout << L"CoInitializeEx failed: " << hr << std::endl;
        return 1;
    }

    IShellItem2* pItem = nullptr;
    hr = SHCreateItemFromParsingName(argv[1], nullptr, IID_PPV_ARGS(&pItem));
    if (SUCCEEDED(hr)) {
        // 获取文件名
        std::wcout << L"File Name: ";
        PrintPropertyValue(pItem, PKEY_ItemNameDisplay);

        // 获取创建日期
        std::wcout << L"Created Date: ";
        PrintPropertyValue(pItem, PKEY_DateCreated);

        // 获取文件作者(如果是文档类文件)
        std::wcout << L"Author: ";
        PrintPropertyValue(pItem, PKEY_FileAuthor);

        // 获取文件描述(如果有)
        std::wcout << L"Description: ";
        PrintPropertyValue(pItem, PKEY_FileDescription);

        pItem->Release();
    } else {
        std::wcout << L"Failed to create Shell item: " << hr << std::endl;
    }

    CoUninitialize();
    return 0;
}

枚举所有文件属性(详情标签里的全部内容)

如果你想一次性获取所有可用的属性及对应值,可以使用IPropertyStore接口来遍历:

void EnumerateAllProperties(IShellItem2* pItem) {
    IPropertyStore* pStore = nullptr;
    if (SUCCEEDED(pItem->GetPropertyStore(GPS_DEFAULT, IID_PPV_ARGS(&pStore)))) {
        DWORD count = 0;
        pStore->GetCount(&count);

        for (DWORD i = 0; i < count; i++) {
            PROPERTYKEY propKey;
            if (SUCCEEDED(pStore->GetAt(i, &propKey))) {
                // 获取属性名称
                PWSTR pPropName = nullptr;
                PSGetNameFromPropertyKey(propKey, &pPropName);
                std::wcout << L"Property: " << pPropName << L" - ";

                // 获取属性值
                PROPVARIANT propVar;
                PropVariantInit(&propVar);
                if (SUCCEEDED(pStore->GetValue(propKey, &propVar))) {
                    // 这里可以复用之前的PrintPropertyValue逻辑处理值
                    switch (propVar.vt) {
                        case VT_LPWSTR:
                            std::wcout << propVar.pwszVal;
                            break;
                        case VT_FILETIME: {
                            SYSTEMTIME st;
                            FileTimeToSystemTime(&propVar.filetime, &st);
                            std::wcout << st.wYear << L"/" << st.wMonth << L"/" << st.wDay;
                            break;
                        }
                        default:
                            std::wcout << L"[Unsupported Type]";
                            break;
                    }
                    PropVariantClear(&propVar);
                }
                std::wcout << std::endl;
                CoTaskMemFree(pPropName);
            }
        }
        pStore->Release();
    }
}

关键注意事项

  • 需要链接shell32.lib和propsys.lib(代码里用#pragma comment已经指定)
  • 必须初始化COM环境(CoInitializeEx),使用完毕后要调用CoUninitialize
  • 不同类型的属性值需要对应不同的PROPVARIANT类型处理,避免内存泄漏
  • 部分属性只有特定类型的文件才有(比如PKEY_FileAuthor只存在于文档、图片等带元数据的文件中)

内容的提问来源于stack exchange,提问作者Baron von Hoot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:25:09