Versioning
Versioning is very important part of software development.In today's world, when digital downloading is the most popular way to distribute software
products, installer version must be easily recognizable. Users should know what version of the application they are using now and what they can download for update.
Server software also need version information to properly display downloading options.
NSIS installers are very convenient for web distribution - all application files are compressed and packed in one executable. The only thing programmer need to do is add version information to installer file.
Hello world (version information in NSIS installer)
The simplest way is to use defines in NSIS script as in following example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!define PRODUCT_MAJOR "1" | |
!define PRODUCT_MINOR "0" | |
!define PRODUCT_TIMESTAMP "13293" | |
!define PRODUCT_BUILD "1" | |
!define PRODUCT_VERSION "${PRODUCT_MAJOR}.${PRODUCT_MINOR}.${PRODUCT_TIMESTAMP}.${PRODUCT_BUILD}" | |
!define PRODUCT_NAME "AwesomeProgram" | |
!define OUT_FILE_NAME "${PPRODUCT_NAME}_${PRODUCT_VERSION}_setup.exe" | |
;set output file name for installer | |
OutFile "${OUT_FILE_NAME}" |
Notice, that versioning model used in this example (and all other examples in this post too) combines four numbers:
- Major version number
- Minor version number
- Time stamp in %YEAR%%DAY_OF_YEAR% format
- Build number
Automatic version increment
Main disadvantage of previous example is that version is absolutely static - all variables are defined in script file and you must change them manually every time you need to rebuild your installer.It's good for a start, but eventually it will become very annoying. Also, static file name makes this code not very useful in any automatic build pipeline.
Hopefully, there are plenty of ways to automate version generation.
For example, you can get system time to produce unique timestamp:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!define PRODUCT_MAJOR "1" | |
!define PRODUCT_MINOR "0" | |
!define /date PRODUCT_TIMESTAMP "%y%j" | |
!define /date PRODUCT_BUILD "%H%M" | |
... |
More complex scripts
With proper usage of NSIS almost everything is possible. Lets assume that we want to update PRODUCT_TIMESTAMP constant every day and increment PRODUCT_BUILD each time NSIS script is compilled.The following code example demonstrates how to use text file to save version information:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!define PRODUCT_MAJOR "1" | |
!define PRODUCT_MINOR "0" | |
!define /date PRODUCT_TIMESTAMP "%y%j" | |
!define BUILDFILE "LastBuild.txt" | |
!include "${BUILDFILE}" | |
!if ${LAST_TIMESTAMP} != ${PRODUCT_TIMESTAMP} | |
!define NEW_BUILD_NUMBER 0 | |
!else | |
!define /math NEW_BUILD_NUMBER ${LAST_BUILD_NUMBER} + 1 | |
!endif | |
!delfile "${BUILDFILE}" | |
!appendfile "${BUILDFILE}" "!define LAST_BUILD_NUMBER ${NEW_BUILD_NUMBER}$\n" | |
!appendfile "${BUILDFILE}" "!define LAST_TIMESTAMP ${PRODUCT_TIMESTAMP}$\n" | |
!define PRODUCT_BUILD "${NEW_BUILD_NUMBER}" | |
!undef BUILDFILE | |
!undef NEW_BUILD_NUMBER | |
!undef LAST_BUILD_NUMBER |
File LastBuild.txt must contain two strings:
!define LAST_TIMESTAMP 13212
!define LAST_BUILD_NUMBER 0
Script will take last timestamp and build number from file, update them, and save in the same file again.
Using existing version file
Very often installer is created for application that already have its own version.In this case installer version must be the same as program this installer is created for.
Lets assume that application version is stored in some source file of your program. The following code can be used to retrieve it when compiling NSIS script:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!define PATH_TO_SOURCE "d:\path\to\source" | |
!searchparse /file ${PATH_TO_SOURCE}\version.h `#define APP_VERSION ` MAJOR `,` MINOR `,` TIMESTAMP `,` BUILD |
File vesion.h must contain following string:
#define APP_VERSION 1,0,13317,1437
For Microsoft Net applications, one can use the following searchparse:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!searchparse /file ${PATH_TO_SOURCE}\Properties\AssemblyInfo.cs `[assembly: AssemblyFileVersion("` PRODUCT_VERSION `")]` |
File properties
NSIS have built in commands ( VIProductVersion and VIAddVersionKey) that can be used to set properties of the installer file on compile-time. Defined constants and variables can be used as parameters:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!define /date BUILD_YEAR "%Y" | |
!define PRODUCT_VERSION "${PRODUCT_MAJOR}.${PRODUCT_MINOR}.${PRODUCT_TIMESTAMP}.${PRODUCT_BUILD}" | |
!define PRODUCT_NAME "AwesomeProgram" | |
!define OUT_FILE_NAME "${PPRODUCT_NAME}_${PRODUCT_VERSION}_setup.exe" | |
;version info | |
VIProductVersion "${PRODUCT_VERSION}" | |
VIAddVersionKey "ProductName" "Awesome Program Installer" | |
VIAddVersionKey "OriginalFilename" "${OUT_FILE_NAME}" | |
VIAddVersionKey "CompanyName" "Awesomness Inc" | |
VIAddVersionKey "LegalCopyright" "Copyright Awesomness Inc ${BUILD_YEAR}" | |
VIAddVersionKey "FileDescription" "Awesome Program - simply awesome" | |
VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}" | |
VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}" | |
VIAddVersionKey "InternalName" "AwesomeProgramBeta" |