Programmversionen

Alles rund um die Programmierung mit Qt
Antworten
Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Programmversionen

Beitrag von Tilman Räger »

Hallo,

in der .pro-Datei besteht die Möglichkeit, Versionsnummern mittels VERSION bzw. der Kombination VER_MAJ, VER_MIN, VER_PAT zu definieren. Beim Erstellen von Bibliotheken unter Linux werden diese Versionsnummer auch schön für die Benennung der .so-Dateien und die Verlinkung verwendet. Gibt es eine Möglichkeit, diese so definierten Versionsnummern
a) unter Windows in eine .rc-Datei zu integrieren bzw.
b) auf diese Konstanten im Quelltext des Programms zuzugreifen?

Bisher habe ich leider noch nichts dazu gefunden - liegt vielleicht auch an mangelnder Phantasie beim googlen ;-)

Gruss

Tilman (Räger)
Volker75
Beiträge: 59
Registriert: 8. April 2009 21:04

Re: Programmversionen

Beitrag von Volker75 »

Evtl hilft dir bei deiner Frage b) etwas wie das folgende im Quelltext:

Code: Alles auswählen

#if QT_VERSION >= 0x050000

#else

#endif
softwaremaker
Beiträge: 149
Registriert: 1. April 2009 19:25

Re: Programmversionen

Beitrag von softwaremaker »

in der .pro kannst du folgendes machen:

Code: Alles auswählen

VERSION = 1.2.3.4
QMAKE_TARGET_COMPANY = "meine firma"
QMAKE_TARGET_PRODUCT = "mein produkt gemacht mit Qt-Version $$[QT_VERSION]"
QMAKE_TARGET_DESCRIPTION = "meine beschreibung"
QMAKE_TARGET_COPYRIGHT = "Copyright (C) 2015"
Bei Windows werden diese Informationen dann in die EXE gepackt und sind als Dateiinfo sichtbar.
// optional kann man in .pro noch definieren:

Code: Alles auswählen

DEFINES += APP_VERSION=\\\"$$VERSION\\\"
DEFINES += APP_PRODUCT=\"\\\"$$QMAKE_TARGET_PRODUCT\\\"\"
und dann in cpp verwenden:

Code: Alles auswählen

QApplication::setApplicationName( APP_PRODUCT );
QApplication::setApplicationVersion( APP_VERSION );
Aber beachten, wenn du VERSION änderst muss die Anwendung komplett neu kompiliert werden, da in .cpp die Änderung von VERSION bzw. APP_VERSION nicht erkannt wird und der Kompiler keine neue Objectdatei erstellt und ::setApplicationName liefert dann noch die alte Versionsnummer.

Alternativ kannst du eine .rc-Datei erstellen und in Qt-Einbinden:
die .rc

Code: Alles auswählen

1 ICON DISCARDABLE "meineappicon.ico"
1 VERSIONINFO
  FILEVERSION 1,2,3,4
  PRODUCTVERSION 1,2,3,4
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
 #else
  FILEFLAGS 0x0L
 #endif
  FILEOS 0x4L
  FILETYPE 0x1L
  FILESUBTYPE 0x0L
 BEGIN
     BLOCK "StringFileInfo"
     BEGIN
         BLOCK "000004e4"
         BEGIN
             VALUE "Comments", "\0"
             VALUE "CompanyName", "meine firma\0"
             VALUE "FileDescription", "dateibeschreibung\0"
             VALUE "FileVersion", "1, 2, 3, 4\0"
             VALUE "InternalName", "dateinameintern\0"
             VALUE "OriginalFilename", "dateiname.exe\0"
             VALUE "PrivateBuild", "\0"
             VALUE "ProductName", "mein produktname\0"
             VALUE "ProductVersion", "1, 2, 3, 4\0"
             VALUE "SpecialBuild", "\0"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x0, 1252
     END
 END
und in der .pro einbinden:

Code: Alles auswählen

RC_FILE = meine_rc_datei.rc
Ich habe mir eine Klasse erstellt, die die Windows-Resource ausliest und daraus die Versionsnummer ermittelt (wurde in .pro mit VERSION gesetzt und landet in der Exe).
versioninfo.h

Code: Alles auswählen

#ifndef VERSIONINFO
#define VERSIONINFO

#include <windows.h>
#include <winver.h>
#include <QCoreApplication>
#include <QDebug>

class VersionInfo
{
public:
    typedef struct
    {
        WORD     major = 0;
        WORD     minor = 0;
        WORD     revision = 0;
        WORD     build = 0;
    } structVersionInfo;

public:
    explicit VersionInfo()
    {
    }

    /*
    static QString ProductVersionString()
    {
        structVersionInfo stVersion;

        ReadVersionInfo( 0, &stVersion );

        return QString( "%1.%2.%3.%4").arg( stVersion.major )
                                      .arg( stVersion.minor )
                                      .arg( stVersion.revision )
                                      .arg( stVersion.build );
    }*/

    static QString FileVersionString()
    {
        structVersionInfo stVersion;

        BYTE *pbVersionInfo = ReadFileVersionInfo( QCoreApplication::applicationFilePath() );

        GetFileVersion( pbVersionInfo, &stVersion );

        return QString( "%1.%2.%3.%4").arg( stVersion.major )
                                      .arg( stVersion.minor )
                                      .arg( stVersion.revision )
                                      .arg( stVersion.build );
    }

    static BYTE* ReadFileVersionInfo( QString filepath )
    {
        DWORD       dwSize              = 0;
        BYTE        *pbVersionInfo      = NULL;

        // filepath to wchar_t
        QByteArray  baApplicationFilePath = filepath.toLatin1();
        const char  *szApplicationFilePath = baApplicationFilePath.constData();
        wchar_t     *szwApplicationFilePath;

        dwSize = 0;
        dwSize = MultiByteToWideChar( CP_ACP, 0, szApplicationFilePath, -1, NULL, 0 );
        if ( 0 == dwSize ) return NULL;
        szwApplicationFilePath = (wchar_t*) new wchar_t[ dwSize ];
        if( NULL == szwApplicationFilePath ) return NULL;
        dwSize = MultiByteToWideChar( CP_ACP, 0, szApplicationFilePath, -1, szwApplicationFilePath, dwSize );

        dwSize = GetFileVersionInfoSize( szwApplicationFilePath, NULL );
        if ( 0 == dwSize ) return NULL;

        pbVersionInfo = new BYTE[ dwSize ];

        if ( !GetFileVersionInfo( szwApplicationFilePath, 0, dwSize, pbVersionInfo ) )
        {
            delete[] pbVersionInfo;
            return NULL;
        }

        return pbVersionInfo;
    }


    static void GetFileVersion( BYTE *pbVersionInfo, structVersionInfo *p_stFileVersion )
    {
        VS_FIXEDFILEINFO    *pFileInfo          = NULL;
        UINT                puLenFileInfo       = 0;

        if ( p_stFileVersion )
        {
            if ( !VerQueryValue( pbVersionInfo, TEXT("\\"), (LPVOID*) &pFileInfo, &puLenFileInfo ) )
            {
                delete[] pbVersionInfo;
                return;
            }

            p_stFileVersion->major    = ( pFileInfo->dwFileVersionMS >> 16 ) & 0xffff;
            p_stFileVersion->minor    = ( pFileInfo->dwFileVersionMS >>  0 ) & 0xffff;
            p_stFileVersion->revision = ( pFileInfo->dwFileVersionLS >> 16 ) & 0xffff;
            p_stFileVersion->build    = ( pFileInfo->dwFileVersionLS >>  0 ) & 0xffff;
        }

        /*
        if ( p_stProductVersion )
        {
            if ( !VerQueryValue( pbVersionInfo, TEXT("\\StringFileInfo\\040904b0\\ProductVersion"), (LPVOID*) &pFileInfo, &puLenFileInfo ) )
            {
                delete[] pbVersionInfo;
                return;
            }

            p_stProductVersion->major    = ( pFileInfo->dwProductVersionMS >> 24 ) & 0xffff;
            p_stProductVersion->minor    = ( pFileInfo->dwProductVersionMS >>  16 ) & 0xffff;
            p_stProductVersion->revision = ( pFileInfo->dwProductVersionLS >> 8 ) & 0xffff;
            p_stProductVersion->build    = ( pFileInfo->dwProductVersionLS >>  0 ) & 0xffff;
        }*/

        delete[] pbVersionInfo;
    }
};
#endif // VERSIONINFO
in der main.cpp kann ich dann die Version verwenden:

Code: Alles auswählen

QApplication app(argc, argv);
app.setApplicationVersion( VersionInfo::FileVersionString() );
Antworten