如果您想模仿 shell 的行为,请使用 shell API,特别是它的 property system。
属性对话框中显示的大部分数据都可以使用一组预定义的常量进行查询,这些常量在“Propkey.h”中定义。在这种情况下,我们需要System.FileDescription property。要查询它,我们需要它的 PKEY,即PKEY_FileDescription。
查询属性的最简单方法之一是IShellItem2::GetString() 方法。 out 参数ppsz 返回一个指向字符串的指针,必须使用CoTaskMemFree() 释放该字符串。参考文献中没有提到这一点,但这是释放 shell 分配给您的内存的常用方法。
要从文件系统路径获取 IShellItem2 接口,我们可以使用SHCreateItemFromParsingName()。
在以下示例中,我将可重用代码封装在函数 GetShellPropStringFromPath() 中。
示例 C++ 控制台应用程序:
#include <Windows.h>
#include <ShlObj.h> // Shell API
#include <Propkey.h> // PKEY_* constants
#include <atlbase.h> // CComPtr, CComHeapPtr
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <string>
#include <system_error>
// Wrapper for SHCreateItemFromParsingName(), IShellItem2::GetString()
// Throws std::system_error in case of any error.
std::wstring GetShellPropStringFromPath( LPCWSTR pPath, PROPERTYKEY const& key )
{
// Use CComPtr to automatically release the IShellItem2 interface when the function returns
// or an exception is thrown.
CComPtr<IShellItem2> pItem;
HRESULT hr = SHCreateItemFromParsingName( pPath, nullptr, IID_PPV_ARGS( &pItem ) );
if( FAILED( hr ) )
throw std::system_error( hr, std::system_category(), "SHCreateItemFromParsingName() failed" );
// Use CComHeapPtr to automatically release the string allocated by the shell when the function returns
// or an exception is thrown (calls CoTaskMemFree).
CComHeapPtr<WCHAR> pValue;
hr = pItem->GetString( key, &pValue );
if( FAILED( hr ) )
throw std::system_error( hr, std::system_category(), "IShellItem2::GetString() failed" );
// Copy to wstring for convenience
return std::wstring( pValue );
}
int main()
{
CoInitialize( nullptr ); // TODO: error handling
_setmode( _fileno( stdout ), _O_U16TEXT ); // for proper UTF-16 console output
try
{
// Show some properties of Microsoft.Photos.exe (adjust path if necessary)
LPCWSTR path = LR"(C:\Program Files\WindowsApps\Microsoft.Windows.Photos_2018.18061.17410.0_x64__8wekyb3d8bbwe\Microsoft.Photos.exe)";
std::wcout << L"PKEY_FileDescription: "
<< GetShellPropStringFromPath( path, PKEY_FileDescription ) << std::endl;
std::wcout << L"PKEY_Software_ProductName: "
<< GetShellPropStringFromPath( path, PKEY_Software_ProductName ) << std::endl;
}
catch( std::system_error const& e )
{
std::cout << "ERROR: " << e.what() << "\nError code: " << e.code() << std::endl;
}
CoUninitialize();
}
输出:
PKEY_FileDescription: Microsoft.Photos.exe
PKEY_Software_ProductName: Microsoft Photos