Thursday 7 March 2013

ProductVersion update for MSI Projects

The script is written in VBScript and is quite simple.

  • read the project file passed in the command line, e.g., Setup.vdproj
  • backup the original file, just in case something goes wrong ;-)
  • find the version number
  • increment the version number
  • replace the version number with the new value
  • replace the product code with a new GUID
  • replace the package code with a new GUID
  • write the updated project file back to disk

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''  Set version number of an MSI setup project from assembly
''  and update relevant GUIDs
''  Chirag Patel /03/03/2013

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

set args = wscript.arguments
if args.count < 2 then wscript.quit 1

set fso = CreateObject("Scripting.FileSystemObject")
set regex = new regexp
regex.global = true

'read current version from Version.txt file...
set versionFile = fso.OpenTextFile(args(1))
strVerTxtFile = versionFile.ReadAll
versionFile.Close

'find version text from file
regex.pattern = "(\d+(\.\d+)+)"
set Matches = regex.Execute(strVerTxtFile)

'split version info text using '.' and create new one with major.minor.svnrev
versionArray = Split(Matches(0).submatches(0), ".")
myNewVer = versionArray(0) & "." & versionArray(1) & "." & versionArray(3)

'Wscript.Echo myNewVer

'read all text from .vdproj of Setup Project
Set vdProjFile = fso.OpenTextFile(args(0))
textOfSetupProj = vdProjFile.ReadAll
vdProjFile.Close

'find and replace version number in .vdproj file
regex.pattern = "(""ProductVersion"" = ""8:)(\d+(\.\d+)+)"""
textOfSetupProj = regex.replace(textOfSetupProj, "$1" & myNewVer & """")

'replace ProductCode
regex.pattern = "(""ProductCode"" = ""8:)(\{.+\})"""
guid = CreateObject("Scriptlet.TypeLib").Guid
guid = left(guid, len(guid) - 2)
textOfSetupProj = regex.replace(textOfSetupProj, "$1" & guid & """")

'replace PackageCode
regex.pattern = "(""PackageCode"" = ""8:)(\{.+\})"""
guid = CreateObject("Scriptlet.TypeLib").Guid
guid = left(guid, len(guid) - 2)
textOfSetupProj = regex.replace(textOfSetupProj, "$1" & guid & """")

'write back to .vbproj file with all the changes that we made above
set vdProjFileNew = fso.CreateTextfile(args(0), true)
vdProjFileNew.write(textOfSetupProj)
vdProjFileNew.close

Save IncrementSetupVersion.vbs 

For auto increment setup project version use scripts IncrementSetupVersion.vbs add them to pre-build events

first argument is setup project file, second is file with assembly version Example: "$(ProjectDir)..\SetupScript\IncrementSetupVersion.vbs" "$(ProjectDir)Setup.vdproj" "$(ProjectDir)..\version.txt"

Insert SVNRevision and Build number in your AssemblyInfo

Insert SVNRevision and Build number in your AssemblyInfo

MSBuild Community Task, you can easily automatically generate smart version numbers, you have to:
**AssemblyInfo Update when project build in release mode


<!-- Import of the MSBuildCommunityTask targets -->
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<!-- to AssemblyInfo to include svn revision number -->
<Target Name="BeforeBuild" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<!-- <Version VersionFile="Version.txt" BuildType="Increment" RevisionType="None">
-->
  <Version Condition=" '$(SkipIncrementAssemblyVersion)' != 'true' " VersionFile="Version.txt" BuildType="None" RevisionType="None">
        <Output TaskParameter="Major" PropertyName="Major" />
        <Output TaskParameter="Minor" PropertyName="Minor" />
        <Output TaskParameter="Build" PropertyName="Build" />
    </Version>
    <SvnVersion LocalPath="$(MSBuildProjectDirectory)" ToolPath="$(ProgramFiles)\VisualSVN\Bin">
        <Output TaskParameter="Revision" PropertyName="Revision" />
    </SvnVersion>

<Time Format="MM/dd/yyyy hh:mm:ss tt">
            <Output TaskParameter="FormattedTime" PropertyName="buildDateTime" />
</Time>
<FileUpdate Files="Properties\AssemblyInfo.cs" Regex="SVN Revision: r(\d+)" ReplacementText="SVN Revision: r$(Revision)" />
<FileUpdate Files="Properties\AssemblyInfo.cs" Regex="Build On: (\d+)\/(\d+)\/(\d+) (\d+)\:(\d+)\:(\d+) ((A|P)M)" ReplacementText="Build On: $(buildDateTime)" />
<FileUpdate Files="Properties\AssemblyInfo.cs" Regex="Build Machine: ([A-Za-z0-9\-]+)" ReplacementText="Build Machine: $(COMPUTERNAME)" />
<FileUpdate Files="Properties\AssemblyInfo.cs" Regex="AssemblyVersion\('(\d+)\.(\d+)\.(\d+)\.(\d+)'\)" ReplacementText="AssemblyVersion('$(Major).$(Minor).$(Build).$(Revision)')" />
<FileUpdate Files="Properties\AssemblyInfo.cs" Regex="AssemblyFileVersion\('(\d+)\.(\d+)\.(\d+)\.(\d+)'\)" ReplacementText="AssemblyFileVersion('$(Major).$(Minor).$(Build).$(Revision)')" />
<FileUpdate Files="Properties\AssemblyInfo.cs" Regex="AssemblyInformationalVersion\('(\d+)'\)" ReplacementText="AssemblyInformationalVersion('$(Revision)')" />
</Target>


You should only have a “</Project>” field left