webentwicklung-frage-antwort-db.com.de

Wie erhalte ich programmgesteuert die Version einer DLL oder EXE-Datei?

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 , aber die Versionsnummern, die angezeigt werden, wenn Sie mit der rechten Maustaste auf eine DLL) -Datei klicken, "Eigenschaften" auswählen und dann die Registerkarte "Details" aufrufen. Dies ist normalerweise eine vierteilige, gepunktete Versionsnummer xxxx.

65
JSBձոգչ

Sie würden die API GetFileVersionInfo 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;
}
97
crashmstr

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

Die ersten beiden Nummern werden im 32-Bit-DWORD dwFileVersionMS und die zweiten beiden in dwFileVersionLS gespeichert. Also habe ich deinen Code im Ausgabebereich 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 einwandfrei. Die Ausgabe ist wie auf meinem System formatiert:

major.Minor.build.Revision

19
Dave Chandler

Sie erhalten diese Informationen über die APIs für Versionsinformationen . 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
        );
}
19
JSBձոգչ

Dieser Code zeigt die Dateiversionsnummern korrekt an.

( pFileInfo->dwFileVersionMS >> 16 ) & 0xff,
( pFileInfo->dwFileVersionMS >> 0 ) & 0xff,
( pFileInfo->dwFileVersionLS >>  16 ) & 0xff,
( pFileInfo->dwFileVersionLS >>  0 ) & 0xff);
8
Vasya

Ich habe diese Artikel gefunden ... Entschuldigung, aber ich habe keine direkten Erfahrungen mit der Verwendung nativer APIs. Daher habe ich mich einer Internetsuche zugewandt:

Hoffe diese Hilfe!

6
Steve J

Am einfachsten ist es, die API-Funktionen GetFileVersionInfoEx oder GetFileVersionInfo zu verwenden.

Sie können dies auch aus Ihren Anwendungsressourcen heraus tun, wie in hier erläutert.

4

Da es in keiner Antwort erwähnt wird ... habe ich herausgefunden, dass Sie müssen unterschiedliche Berechnungen durchführen, 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;
}
0
Amadeus Hein