问题描述
我正在尝试提取可执行文件的文件描述.右键单击文件,选择属性",然后在常规"选项卡中,便会看到文件描述.
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.
我尝试使用此处找到的算法: https://docs.microsoft.com/zh-cn/windows/desktop/api/winver/nf-winver-verqueryvaluea ,但是对于某些文件,返回的文件描述为空,尽管我可以在属性窗口.例如,如果我创建一个可执行文件,则返回的文件描述将为空,但是在属性"窗口中,其文件描述与其名称相同.如何为常规"选项卡中包含一个可执行文件的每个可执行文件提取文件描述,而不会得到空字符串?
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
GetFileVersionInfoSize
GetFileVersionInfo
GetFileVersionInfo
VerQueryValue
VerQueryValue
StringCchPrintfW
StringCchPrintfW
VerQueryValue
VerQueryValue
StringCchCopyNW
StringCchCopyNW
有时它在VerQueryValue失败,有时在GetFileVersionInfo失败.我还注意到Microsoft.Photos.exe
Sometimes it fails at VerQueryValue and sometimes it fails at GetFileVersionInfo. I have also noticed that it fails for Microsoft.Photos.exe
推荐答案
如果要模仿shell行为,请使用shell API,特别是产权系统.
If you want to mimic the shells behaviour, use the shell API, specifically its property system.
可以使用在"Propkey.h"中定义的一组预定义常数来查询属性对话框中所示的大多数数据.在这种情况下,我们需要 System.FileDescription属性一个>.要查询它,我们需要它的PKEY,它是 PKEY_FileDescription
.
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
.
查询属性最简单的方法之一是 IShellItem2 :: GetString()
方法.out参数 ppsz
返回指向字符串的指针,必须使用 CoTaskMemFree()
将其释放.该参考文献未提及,但这是释放外壳程序为您分配的内存的常用方法.
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.
要从文件系统路径获取IShellItem2接口,我们可以使用 SHCreateItemFromParsingName()
.
To obtain an IShellItem2 interface from a filesystem path, we can use SHCreateItemFromParsingName()
.
在下面的示例中,我将可重用代码包装在函数 GetShellPropStringFromPath()
中.
In the following example, I've wrapped up the reusable code in the function 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
这篇关于如何使用WINAPI和C ++提取可执行文件的文件描述?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!