I want to get the description of a process (the description that is seen in task manager) in Windows using C++.
Although I read this question, the accepted answer, and the documentation for VerQueryValue
, I spent quite a while to understand how to use that VerQueryValue
function (since the code example in the docs has no declarations of variables and isn't clear for me at all).
So I decided to put here the code that can be easily run as a working example of the usage of VerQueryValue
to get a process description.
#pragma comment(lib,"Version.lib")
#include <iostream>
#include <windows.h>
#include <winver.h>
using namespace std;
int printFileDescriptions(const wchar_t* filename)
{
int versionInfoSize = GetFileVersionInfoSize(filename, NULL);
if (!versionInfoSize) {
return 0;
}
auto versionInfo = new BYTE[versionInfoSize];
std::unique_ptr<BYTE[]> versionInfo_automatic_cleanup(versionInfo);
if (!GetFileVersionInfo(filename, NULL, versionInfoSize, versionInfo)) {
return 0;
}
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *translationArray;
UINT translationArrayByteLength = 0;
if (!VerQueryValue(versionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayByteLength)) {
return 0;
}
// You may check GetSystemDefaultUILanguage() == translationArray[i].wLanguage
// if only the system language required
for (unsigned int i = 0; i < (translationArrayByteLength / sizeof(LANGANDCODEPAGE)); i++) {
wchar_t fileDescriptionKey[256];
wsprintf(
fileDescriptionKey,
L"\\StringFileInfo\\%04x%04x\\FileDescription",
translationArray[i].wLanguage,
translationArray[i].wCodePage
);
wchar_t* fileDescription = NULL;
UINT fileDescriptionSize;
if (VerQueryValue(versionInfo, fileDescriptionKey, (LPVOID*)&fileDescription, &fileDescriptionSize)) {
wcout << endl << fileDescription << endl;
}
}
return TRUE;
}
int main()
{
// Set locale of the console to print non-ASCII symbols
SetConsoleOutputCP(GetACP());
SetConsoleCP(GetACP());
wcout.imbue(std::locale("")); // set default global locale
// ----------------------------------------------------
auto path = L"C:\\Windows\\explorer.exe";
printFileDescriptions(path);
wcin.get(); // to prevent console close
}
It's supposed that all WinAPI functions on your system use wchar_t
, that is VerQueryValueW
is actually used.
The initial version of the code I took here Retrieve File Description an Application VerQueryValue
You most likely want to get the FileDesription
field from the version resources of the main .exe
file of the program, using the VerQueryValue() API call. Here is an example from that document:
The following example shows how to enumerate the available version languages and retrieve the FileDescription string-value for each language.
Be sure to call the GetFileVersionInfoSize and GetFileVersionInfo functions before calling VerQueryValue to properly initialize the pBlock buffer.
// Structure used to store enumerated languages and code pages. HRESULT hr; struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } *lpTranslate; // Read the list of languages and code pages. VerQueryValue(pBlock, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate); // Read the file description for each language and code page. for( i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ ) { hr = StringCchPrintf(SubBlock, 50, TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"), lpTranslate[i].wLanguage, lpTranslate[i].wCodePage); if (FAILED(hr)) { // TODO: write error handler. } // Retrieve file description for language and code page "i". VerQueryValue(pBlock, SubBlock, &lpBuffer, &dwBytes); }