[英]How to extract file description of executables using WINAPI and C++?
我正在嘗試提取可執行文件的文件描述。 文件描述是在您右鍵單擊文件時看到的描述,選擇“屬性”,它位於“常規”選項卡中。
我嘗試使用此處找到的算法: https : //docs.microsoft.com/en-us/windows/desktop/api/winver/nf-winver-verqueryvaluea但對於某些文件,返回的文件描述為空,盡管我可以看到它在“屬性”窗口中。 例如,如果我創建一個可執行文件,返回的文件描述將為空,但在“屬性”窗口中,其文件描述與其名稱相同。 如何提取每個在“常規”選項卡中有一個可執行文件的文件描述而不是空字符串?
我按以下順序使用這些功能:
獲取文件版本信息大小
獲取文件版本信息
查詢值
StringCchPrintfW
查詢值
StringCchCopyNW
有時在 VerQueryValue 處失敗,有時在 GetFileVersionInfo 處失敗。 我還注意到 Microsoft.Photos.exe 失敗
如果您想模仿 shell 行為,請使用 shell API,特別是它的屬性 system 。
屬性對話框中顯示的大部分數據都可以使用一組預定義的常量進行查詢,這些常量在“Propkey.h”中定義。 在這種情況下,我們需要System.FileDescription 屬性。 要查詢它,我們需要它的 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.