简体   繁体   中英

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

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 tab.

I have tried using the algorithm found here: https://docs.microsoft.com/en-us/windows/desktop/api/winver/nf-winver-verqueryvaluea but for some files the file description returned is empty although I can see it in the Properties window. For example, if I create an executable the file description returned will be empty, but in the Properties window its file description is the same as its name. How can I extract the file description for every executable that has one in the General tab and not get empty strings?

I am using the functions in the following order:

GetFileVersionInfoSize

GetFileVersionInfo

VerQueryValue

StringCchPrintfW

VerQueryValue

StringCchCopyNW

Sometimes it fails at VerQueryValue and sometimes it fails at GetFileVersionInfo. I have also noticed that it fails for Microsoft.Photos.exe

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM