簡體   English   中英

如何使用 WINAPI 和 C++ 提取可執行文件的文件描述?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM