Search code examples
inno-setup

Extracting application version number using Inno Setup (but excluding the fourth number)


I have been reading with interest about using API calls to extract information from the executable during compilation of the setup file. Example: Using GetStringFileInfo in Setup section of Inno Setup

In my script I have the following:

[ISPP]
; Please, don't edit this section manually if you don't know what are you doing.
#define DataDir "{userappdata}\Meeting Schedule Assistant"
#define CommonDataDir "{commonappdata}\Meeting Schedule Assistant"
#define AppVerText "18.1.5"
#define AppURL "http://www.publictalksoftware.co.uk"
#define AppPublisher "Andrew Truckle"

At the moment, I use the above like this:

[Setup]
AppName=Meeting Schedule Assistant
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
DefaultDirName={pf}\Meeting Schedule Assistant
DefaultGroupName=Meeting Schedule Assistant
SourceDir=..\Meeting Schedule Assistant\Release
; NOTE: Paths are now RELATIVE to ..\Release
; NOTE: But NOT for #includes
OutputDir=..\..\inno\Output
OutputBaseFilename=MeetSchedAssistSetup
AppCopyright=Andrew Truckle © 2003 - 2018
AppVersion={#AppVerText}
VersionInfoVersion={#AppVerText}
VersionInfoCompany={#AppPublisher}
VersionInfoDescription=Meeting Schedule Assistant
VersionInfoTextVersion={#AppVerText}
VersionInfoCopyright=Andrew Truckle © 2003 - 2018

I have cut alot of it out. I just wanted to show you what I am doing. Now, my executable has the following version information:

Version Info

Given the above setup, is it possible for me to extract the version number, but, only the 18.1.5 bit (I don't show the fourth value as it is usually used for beta increments internally).

I don't want to overcomplicate my script. It is is going to be easier to just change my ISPP value for AppVerText I will. But if I could automate it it would reduce one maintenance issue.

Update

Based on the answer I added this code:

#define AppVerText() \
   GetVersionComponents('..\Meeting Schedule Assistant\Release\Meeting Schedule Assistant.exe', Local[0], Local[1], Local[2], Local[3]), \
   Str(Local[0]) + "." + Str(Local[1]) + "." + Str(Local[2])

I tried to change it to use {#SetupSetting('SourceDir')}\Meeting Schedule Assistant.exe like this:

#define AppVerText() \
   GetVersionComponents('{#SetupSetting('SourceDir')}\Meeting Schedule Assistant.exe', Local[0], Local[1], Local[2], Local[3]), \
   Str(Local[0]) + "." + Str(Local[1]) + "." + Str(Local[2])

But it complained:

Error


Solution

  • Use GetVersionComponents preprocessor function and then assemble a version string any way you like:

    #define AppVerText() \
       GetVersionComponents('MyProg.exe', Local[0], Local[1], Local[2], Local[3]), \
       Str(Local[0]) + "." + Str(Local[1]) + "." + Str(Local[2])
    
    [Setup]
    AppVersion={#AppVerText}
    

    I tried to change it to use {#SetupSetting('SourceDir')}\Meeting Schedule Assistant.exe ... but it failed.

    SetupSetting is a preprocessor function and you are using it inside a preprocessor expression, just like GetVersionComponents. So do not use {# ... } again to escape to preprocessor, as you are already there (see Why preprocessor behaves differently in #include directive then in [Files] section Inno Setup script). This is the right syntax:

    #define AppVerText() \
       GetVersionComponents( \
         SetupSetting('SourceDir') + '\Meeting Schedule Assistant.exe', \
         Local[0], Local[1], Local[2], Local[3]), \
       Str(Local[0]) + "." + Str(Local[1]) + "." + Str(Local[2])
    

    Though I'd personally use a preprocesor define like this:

    #define SourceDir "..\Meeting Schedule Assistant\Release"
    #define AppVerText() \
       GetVersionComponents( \
         SourceDir + '\Meeting Schedule Assistant.exe', \
         Local[0], Local[1], Local[2], Local[3]), \
       Str(Local[0]) + "." + Str(Local[1]) + "." + Str(Local[2])
    
    [Setup]
    SourceDir={#SourceDir}
    AppVersion={#AppVerText}
    

    Finally, notice that these code examples make use of an array called Local. That's why AppVerText is declared as a parameter-less macro (note the empty brackets after AppVerText), rather than a mere variable. Variable declarations do not have the Local array, while macro declarations do.