Ich muss die Produktversion und die Dateiversion für eine DLL- oder EXE-Datei mit nativen Win32-APIs in C oder C ++ abrufen. Ich suche nicht nach der Windows-Version, sondern nach den Versionsnummern, die Sie sehen, wenn Sie mit der rechten Maustaste auf eine DLL-Datei klicken, "Eigenschaften" auswählen und dann auf die Registerkarte "Details" klicken. Dies ist normalerweise eine vierteilige gepunktete Versionsnummer xxxx
73
Antworten:
Sie würden die GetFileVersionInfo- API verwenden.
Siehe Verwenden von Versionsinformationen auf der MSDN-Site.
Stichprobe:
DWORD verHandle = 0; UINT size = 0; LPBYTE lpBuffer = NULL; DWORD verSize = GetFileVersionInfoSize( szVersionFile, &verHandle); if (verSize != NULL) { LPSTR verData = new char[verSize]; if (GetFileVersionInfo( szVersionFile, verHandle, verSize, verData)) { if (VerQueryValue(verData,"\\",(VOID FAR* FAR*)&lpBuffer,&size)) { if (size) { VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *)lpBuffer; if (verInfo->dwSignature == 0xfeef04bd) { // Doesn't matter if you are on 32 bit or 64 bit, // DWORD is always 32 bits, so first two revision numbers // come from dwFileVersionMS, last two come from dwFileVersionLS TRACE( "File Version: %d.%d.%d.%d\n", ( verInfo->dwFileVersionMS >> 16 ) & 0xffff, ( verInfo->dwFileVersionMS >> 0 ) & 0xffff, ( verInfo->dwFileVersionLS >> 16 ) & 0xffff, ( verInfo->dwFileVersionLS >> 0 ) & 0xffff ); } } } } delete[] verData; }
quelle
int revision = HIWORD(verInfo->dwProductVersionLS); int build = LOWORD(verInfo->dwProductVersionLS);
TCHAR szVersionFile[MAX_PATH]; GetModuleFileName(NULL, szVersionFile, MAX_PATH );
NULL
sollte nicht mitDWORD
s verwendet werden (0
wäre stattdessen korrekt)Alle diese Lösungen funktionierten nicht richtig (mit meinem System). Ich fand heraus, dass jeder der vier Teile der Versionsnummer als 16-Bit-Wert gespeichert ist.
Die ersten beiden Nummern werden im 32-Bit-DWORD dwFileVersionMS und die zweiten beiden in dwFileVersionLS gespeichert. Also habe ich Ihren Code im Ausgabeabschnitt folgendermaßen bearbeitet:
TRACE( "File Version: %d.%d.%d.%d\n", ( pFileInfo->dwFileVersionMS >> 16 ) & 0xffff, ( pFileInfo->dwFileVersionMS >> 0 ) & 0xffff, ( pFileInfo->dwFileVersionLS >> 16 ) & 0xffff, ( pFileInfo->dwFileVersionLS >> 0 ) & 0xffff );
Und es funktioniert perfekt. Die Ausgabe ist wie auf meinem System formatiert:
major.minor.build.revision
quelle
Sie erhalten diese Informationen über die Versionsinformations-APIs . Hier ist ein Beispiel:
void PrintFileVersion( TCHAR *pszFilePath ) { DWORD dwSize = 0; BYTE *pbVersionInfo = NULL; VS_FIXEDFILEINFO *pFileInfo = NULL; UINT puLenFileInfo = 0; // Get the version information for the file requested dwSize = GetFileVersionInfoSize( pszFilePath, NULL ); if ( dwSize == 0 ) { printf( "Error in GetFileVersionInfoSize: %d\n", GetLastError() ); return; } pbVersionInfo = new BYTE[ dwSize ]; if ( !GetFileVersionInfo( pszFilePath, 0, dwSize, pbVersionInfo ) ) { printf( "Error in GetFileVersionInfo: %d\n", GetLastError() ); delete[] pbVersionInfo; return; } if ( !VerQueryValue( pbVersionInfo, TEXT("\\"), (LPVOID*) &pFileInfo, &puLenFileInfo ) ) { printf( "Error in VerQueryValue: %d\n", GetLastError() ); delete[] pbVersionInfo; return; } // pFileInfo->dwFileVersionMS is usually zero. However, you should check // this if your version numbers seem to be wrong printf( "File Version: %d.%d.%d.%d\n", ( pFileInfo->dwFileVersionLS >> 24 ) & 0xff, ( pFileInfo->dwFileVersionLS >> 16 ) & 0xff, ( pFileInfo->dwFileVersionLS >> 8 ) & 0xff, ( pFileInfo->dwFileVersionLS >> 0 ) & 0xff ); // pFileInfo->dwProductVersionMS is usually zero. However, you should check // this if your version numbers seem to be wrong. printf( "Product Version: %d.%d.%d.%d\n", ( pFileInfo->dwProductVersionLS >> 24 ) & 0xff, ( pFileInfo->dwProductVersionLS >> 16 ) & 0xff, ( pFileInfo->dwProductVersionLS >> 8 ) & 0xff, ( pFileInfo->dwProductVersionLS >> 0 ) & 0xff ); }
quelle
Dieser Code zeigt die Versionsnummern der Datei korrekt an.
( pFileInfo->dwFileVersionMS >> 16 ) & 0xff, ( pFileInfo->dwFileVersionMS >> 0 ) & 0xff, ( pFileInfo->dwFileVersionLS >> 16 ) & 0xff, ( pFileInfo->dwFileVersionLS >> 0 ) & 0xff);
quelle
Diese Artikel gefunden ... Entschuldigung, aber ich habe keine direkte Erfahrung damit, wie dies mit nativen APIs gemacht wird. Daher habe ich mich auf eine Internetsuche beschränkt:
Hoffe diese Hilfe!
quelle
Am einfachsten ist es, die API-Funktionen GetFileVersionInfoEx oder GetFileVersionInfo zu verwenden.
Sie können dies auch aus Ihren Anwendungsressourcen heraus tun, wie hier erläutert .
quelle
Da keine der Antworten dies erwähnt ... Ich habe herausgefunden, dass Sie unterschiedliche Berechnungen durchführen müssen, je nachdem, ob Sie auf 32- oder 64-Bit-Systemen arbeiten . Deshalb finden Sie, dass bestimmte Antworten in dieser Frage für Sie funktionieren und andere nicht.
Hier ist eine Beispielimplementierung, die ich verwende:
if(IsWow64()) { // 64 bit build major = (verInfo->dwProductVersionMS >> 16) & 0xffff; minor = (verInfo->dwProductVersionMS >> 0) & 0xffff; revision = (verInfo->dwProductVersionLS >> 16) & 0xffff; build = (verInfo->dwProductVersionLS >> 0) & 0xffff; } else { // 32 bit build major = HIWORD(verInfo->dwProductVersionMS); minor = LOWORD(verInfo->dwProductVersionMS); revision = HIWORD(verInfo->dwProductVersionLS); build = LOWORD(verInfo->dwProductVersionLS); }
Und die Implementierung von IsWow64 (nicht von mir):
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process; BOOL IsWow64() { BOOL bIsWow64 = FALSE; //IsWow64Process is not available on all supported versions of Windows. //Use GetModuleHandle to get a handle to the DLL that contains the function //and GetProcAddress to get a pointer to the function if available. fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress( GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); if(NULL != fnIsWow64Process) { if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { // Handle error... } } return bIsWow64; }
quelle
DWORD
s, die in zweiWORD
s aufgeteilt werden können. Ihre 64-Bit-Bedingungen scheinen auch jeden Wert auf 255 anstatt auf 32767 zu kürzen.edit
auf den Beitrag klicken , sollten Sie die Möglichkeit haben, Änderungsvorschläge zu erstellen, die die Moderatoren dann genehmigen / ablehnen.DWORD
Werte für 32-Bit- und 64-Bit-Builds. Bei einem 64-Bit-Build verlängern die MakrosHIWORD()
undLOWORD()
dasDWORD
s auf null bis 64DWORD_PTR
Bit, bevor sie bitverschoben werden. Das Endergebnis sind jedoch dieselben Werte. AußerdemIsWow64()
erkennt ein 64bit Build sowieso nicht.IsWow64Process()
Gibt TRUE nur für einen 32-Bit-Build zurück, der in WOW64 ausgeführt wird. Es handelt sich also immer noch um einen 32-Bit-Build. Um zwischen 32-Bit- und 64-Bit-Builds zu unterscheiden, müssen Sie#if(n)def _WIN64
stattdessen verwenden.