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!

Tuesday, November 17, 2009

The Channel 9 Learning Center

If you want to learn the latest Microsoft technologies such as V2010 and .NET 4.0, Windows Azure, and SharePoint 2010, then check it out the training course available at Channel 9 Learning Center: