Saturday, November 28, 2009

Setting Assembly Version with Windows PowerShell

I've been using the Build Version Increament add-in for Visual Studio to automatically set the assembly and file versions. It works fine, however, it only works when using the Visual Studio IDE and it requires you to setup every single project of your solution. If you need to increment the assembly version on an automated build (MS Build, NAnt, PSake), then a PowerShell script would be a better solution.

The following script, SetVersion.ps1, searches for AssemblyInfo.cs files in the current directory and its sub directories, and then updates the AssemblyVersion and AssemblyFileVersion. You can optionally provide the version number to use, or it will auto generate one for you. You can customize the Generate-VersionNumber function to use your own version schema. Also, if you are using a source control that needs to check-out files before editing them, such as TFS and Perforce, then add the check-out command to the Update-AssemblyInfoFiles function.

# Displays how to use this script.
function Help {
    "Sets the AssemblyVersion and AssemblyFileVersion of AssemblyInfo.cs files`n"
    ".\SetVersion.ps1 [VersionNumber]`n"
    "   [VersionNumber]     The version number to set, for example: 1.1.9301.0"
    "                       If not provided, a version number will be generated.`n"

# Generate a version number.
# Note: customize this function to generate it using your version schema.
function Generate-VersionNumber {
    $today = Get-Date
    return "1.0." + ( ($today.year - 2000) * 1000 + $today.DayOfYear )+ ".0"
# Update version numbers of AssemblyInfo.cs
function Update-AssemblyInfoFiles ([string] $version) {
    $assemblyVersionPattern = 'AssemblyVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)'
    $fileVersionPattern = 'AssemblyFileVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)'
    $assemblyVersion = 'AssemblyVersion("' + $version + '")';
    $fileVersion = 'AssemblyFileVersion("' + $version + '")';
    Get-ChildItem -r -filter AssemblyInfo.cs | ForEach-Object {
        $filename = $_.Directory.ToString() + '\' + $_.Name
        $filename + ' -> ' + $version
        # If you are using a source control that requires to check-out files before 
        # modifying them, make sure to check-out the file here.
        # For example, TFS will require the following command:
        # tf checkout $filename
        (Get-Content $filename) | ForEach-Object {
            % {$_ -replace $assemblyVersionPattern, $assemblyVersion } |
            % {$_ -replace $fileVersionPattern, $fileVersion }
        } | Set-Content $filename

# Parse arguments.
if ($args -ne $null) {
    $version = $args[0]
    if (($version -eq '/?') -or ($version -notmatch "[0-9]+(\.([0-9]+|\*)){1,3}")) {
} else {
    $version =  Generate-VersionNumber

Update-AssemblyInfoFiles $version

And finally, before running this script, or any PowerShell script, make sure that you are allowed to execute scripts by running Get-ExecutionPolicy. If it returns Restricted, you need to run the following command:

Set-ExecutionPolicy RemoteSigned

Download the entire script from here.

Enjoy it!


Anonymous said...

Awesome, just what i was looking to do! using this in a CI server.

Anonymous said...

Perfect! Works great with TeamCity.

Spring Boot Configuration Properties Localization

Spring Boot allows to externalize application configuration by using properties files or YAML files. Spring Profiles  provide a way to segr...