How to extract file description of executables using WINAPI and C++?

前端 未结 1 2009
清歌不尽
清歌不尽 2021-01-07 12:12

I am trying to extract the file description of executables. The file description is the one seen when you right click on a file, choose Properties and it is in the General t

相关标签:
1条回答
  • 2021-01-07 12:49

    If you want to mimic the shells behaviour, use the shell API, specifically its property system.

    Most of the data shown in the properties dialog can be queried using a set of predefined constants, which are defined in "Propkey.h". In this case we want the System.FileDescription property. To query it, we need its PKEY, which is PKEY_FileDescription.

    One of the easiest ways to query a property is the IShellItem2::GetString() method. The out parameter ppsz returns a pointer to a string, which must be freed using CoTaskMemFree(). This is not mentioned by the reference, but is the usual way to free memory allocated for you by the shell.

    To obtain an IShellItem2 interface from a filesystem path, we can use SHCreateItemFromParsingName().

    In the following example, I've wrapped up the reusable code in the function GetShellPropStringFromPath().

    Example C++ console application:

    #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();
    }
    

    Output:

    PKEY_FileDescription:      Microsoft.Photos.exe
    PKEY_Software_ProductName: Microsoft Photos
    
    0 讨论(0)
提交回复
热议问题