Click here to Skip to main content
15,860,844 members
Articles / Programming Languages / XML
Article

Auto Increment Visual Studio 2005 version build and revision number on compile time

Rate me:
Please Sign up or sign in to vote.
4.67/5 (12 votes)
10 Mar 20063 min read 275.9K   973   63   55
Auto increment Visual Studio 2005 version build and revision number on compile.

Introduction

In Visual Studio 2005, the version numbers don't auto increment when you build your project. Annoying? I think so. So, I set out to find a way to do it. I did find some sample bits of code on the net that said would do it, and while they did work to a point, they didn't work well, or at all.

So, I set out to write my own using what I learned from the tutorials.

Using the code

Create a Windows DLL project, doesn't have to be anything special. In the default class, put the following:

VB
Imports System
Imports Microsoft.Build.Framework
Imports Microsoft.Build.Utilities

Namespace BuildTasks
    Public Class IncrementBuildNumber
        Inherits Task

        Dim m_AssemblyFileLocation As String 
        ' This is the Assembly file
        ' that has the version info.

        Public Overrides Function _
               Execute() As Boolean
            Try
                Return IncrementVersion()
            Catch ex As Exception
                Log.LogError(ex.Message)
                Return False
            End Try
        End Function 'Execute 

        <Required()> Public Property _
                AssemblyFileLocation() As String
            Get
                Return m_AssemblyFileLocation
            End Get
            Set(ByVal value As String)
                m_AssemblyFileLocation = value
            End Set
        End Property

        Private Function IncrementVersion() As Boolean

            Dim i As Integer
            Dim FileData() As String
            Dim s As String
            Dim Version As String
            Dim v() As String
            Dim ResetRevision As Boolean = True

            ' All the commented msgbox
            ' lines are for debugging.
            ' you don't need them.

            'If MsgBox("IncrementVersion Run on file " & _
                        m_AssemblyFileLocation & _
                        vbNewLine & _
                        vbNewLine & _
                        "Copy path to clipboard?", _
                        MsgBoxStyle.YesNo) = _
                        MsgBoxResult.Yes Then
            '    My.Computer.Clipboard.Clear()
            '    My.Computer.Clipboard.
            '        SetText(m_AssemblyFileLocation)
            'End If


            ' Ok, we have the assembly file, try to open it.
            If IO.File.Exists(m_AssemblyFileLocation) Then

                ' Set build number to the number
                ' of days that have passed since Jan 1 2000
                ' If you want to modifiy what
                ' the build number means or does,
                ' here is the place.
                Dim Major As Integer = 1
                Dim Minor As Integer = 0
                Dim BuildNumber As Integer = _
                   Math.Abs(DateDiff(DateInterval.Day, _
                   Now.Date, CType("JAN/01/2000", Date)))
                Dim Revision As Integer = 0

                'MsgBox("New build number = " & BuildNumber)

                Try
                    FileData = _
                      IO.File.ReadAllLines(m_AssemblyFileLocation)

                    'MsgBox("Read " & FileData.Length & _
                            " lines from " & m_AssemblyFileLocation)

                    If FileData.Length = 0 Then Exit Function
                    ' loop through each line
                    's and look for the version lines.
                    For i = 0 To FileData.Length - 1
                        s = FileData(i)
                        If s.Length > 2 Then
                            ' Look to see if it contains
                            ' one of the 2 version lines we want.
                            'VB: <Assembly: AssemblyVersion("0.0.0.0")> 
                            'VB: <Assembly: AssemblyFileVersion("0.0.0.0")> 
                            'C#: [assembly: AssemblyFileVersion("1.0.0.0")]
                            'C#: [assembly: AssemblyVersion("1.0.0.0")]
                            If Not s.Substring(0, 1) = "'" _
                              And Not s.Substring(0, 2) = "//" Then

                                If s.Contains("AssemblyVersion") _
                                      Or s.Contains("AssemblyFileVersion") Then

                                  'MsgBox("Target line " & s _
                                  '   & " found, parsing now.")

                                  ' Get the version from the line.
                                  ' we do this by getting the first
                                  ' " and losing everything before it.
                                  ' do the same after the next "
                                  ' everything left should be version info.
                                  Version = _
                                      Microsoft.VisualBasic.Right(s, _
                                      s.Length - s.IndexOf(Chr(34)) - 1)
                                  Version = _
                                      Microsoft.VisualBasic.Left(Version, _
                                      Version.IndexOf(Chr(34)))

                                  'MsgBox("Version found = " & Version)

                                  v = Version.Split(".")
                                  If v.Length >= 0 Then
                                      Major = Val(v(0))
                                  If v.Length >= 1 Then
                                      Minor = Val(v(1))
                                  If v.Length >= 2 Then
                                      ResetRevision = _
                                        (BuildNumber <> Val(v(2)))
                                  If v.Length >= 3 Then
                                      Revision = Val(v(3)) + 1

                                  ' ok, now that we have
                                  ' the version numbers in their variables
                                  ' it's time to update
                                  ' the build, if needed.
                                  If ResetRevision Then
                                      Revision = 1

                                  'MsgBox("Replacing version with " _
                                  '& Major & "." & Minor & "." & _
                                  'BuildNumber & "." & Revision)

                                  ' ok, update the original
                                  ' line from the array.
                                  FileData(i) = _
                                    FileData(i).Replace(Version, _
                                    Major & "." & Minor & "." & _
                                    BuildNumber & "." & Revision)

                                  'MsgBox("Filedata(" & i _
                                  '   & ") = " & FileData(i))
                                End If
                            End If
                        End If
                    Next

                    ' ok, rewrite the assembly info back
                    ' into the file, and let's home
                    ' the compiler picks it up
                    'MsgBox("writing all data back to file")
                    IO.File.WriteAllLines(m_AssemblyFileLocation, _
                                                        FileData)


                Catch ex As Exception
                    ' hrm. Error. Fail please.
                    MsgBox("ERROR! " & ex.Message, "Build Tasks")
                    Log.LogError(ex.Message)
                    Return False
                End Try
            End If

            ' return success
            Return True
        End Function

    End Class
End Namespace

Now... how do we use it? I mean, you have a wonderful DLL file now... but how is it applied to your project? Well, you need to first copy your DLL into the same folder as your project file. Do not confuse the "solution" file (.sln) with your project file (.vbproj) as they are not the same thing.

Once the file is copied, open the .vbproj file in Notepad or some other text editor, so you can see the raw info.

Add the following line to the project file after the <project> tag and before the first <propertygroup> tag.

XML
<UsingTask TaskName="BuildTasks.IncrementBuildNumber" 
            AssemblyFile="BuildTask.dll" />

An example of one of my project files would look like this, then:

XML
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" 
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask TaskName="BuildTasks.IncrementBuildNumber" 
     AssemblyFile="BuildTask.dll" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">
               Debug</Configuration>
    
    ...

Scroll on down till you find the <Target Name="BeforeBuild"> tag. It may be commented out; uncomment it out, and between the open and close tags, add the following:

XML
<IncrementBuildNumber AssemblyFileLocation = 
    "$(MSBuildProjectDirectory)\My Project\AssemblyInfo.vb">
</IncrementBuildNumber>

Note! Make sure the path to your assembly file is correct. If it's not in the "My Projects" folder, make sure you adjust your line above to say where it is. The $(MSBuildProjectDirectory) variable will be replaced with the folder the .vbproj file is in. So if the assembly.vb file is in the same location, then do use any subfolder. By default, VS 2005 puts it in the "My Projects" folder and calls it AssemblyInfo.vb. For C#, it's AssemblyInfo.cs.

This DLL should work for both C# and VB projects, hell, it should for all VS projects... but I only tested it with C# and VB.

Save the project file and then open it in VS. Now, every time you build the project, VS will call the IncrementBuildNumber class in the DLL and execute the code in it. The code itself opens your assembly file, edits the version info, then saves it.

Because you are doing this in the "BeforeBuild" section, it will be done before you build. Neat eh?

Note: Some project files may not have the <Target Name="BeforeBuild"> tags. If this is the case, I usually just add them after the <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" /> line.

I.e.:

XML
<Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
<Target Name="BeforeBuild">
  <IncrementBuildNumber AssemblyFileLocation=
           "$(MSBuildProjectDirectory)\AssemblyInfo.vb">
  </IncrementBuildNumber>
  </Target>
  <Target Name="AfterBuild">
  </Target>
</Project>

Points of Interest

Sometimes, the revision number will jump 2 or 3 numbers. I don't know why, I can only assume that something is not re-loading correctly or that the compiler is calling the DLL twice or more. I don't really care actually, so I never bothered trying to fix it.

Also, if you have the project properties window, or the assembly file open, the version may not increment. Again, I didn't care enough about something so minor to spend time trying to fix it. Feel free to let me know if you find out why.

History

  • 1.0.0.0 - initial release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionTry this...it's pretty flexible Pin
Greg Osborne14-May-18 11:33
Greg Osborne14-May-18 11:33 
QuestionAuto Increment version build on compile time Pin
DOVAX25-Feb-13 5:12
DOVAX25-Feb-13 5:12 
GeneralAuto increment versioning for .net 2008/2010 Pin
Rod Steele13-May-10 4:13
Rod Steele13-May-10 4:13 
Generalconverting build number to build date Pin
AndrusM16-Jun-09 0:37
AndrusM16-Jun-09 0:37 
QuestionVista x64 issue? Pin
conniek17-May-09 12:45
conniek17-May-09 12:45 
GeneralWORKS GREAT! Pin
taziscool16-Feb-09 8:59
taziscool16-Feb-09 8:59 
GeneralJust remove the AssemblyFIleVerion Line from the AssemblyInfo file Pin
Andrewiski6-Dec-08 5:08
Andrewiski6-Dec-08 5:08 
QuestionIs there a better way to do this? Pin
remarkpk113-Sep-08 17:59
remarkpk113-Sep-08 17:59 
QuestionHow to get Auto Increment to work with Fortran? Pin
roonwhit16-Oct-07 17:38
professionalroonwhit16-Oct-07 17:38 
General"BuildTasks" string error. Pin
arekkusu8227-Sep-07 14:01
arekkusu8227-Sep-07 14:01 
GeneralRe: "BuildTasks" string error. Pin
Mystify28-Sep-07 1:07
Mystify28-Sep-07 1:07 
GeneralRe: "BuildTasks" string error. Pin
arekkusu8228-Sep-07 7:43
arekkusu8228-Sep-07 7:43 
GeneralRe: "BuildTasks" string error. Pin
arekkusu8228-Sep-07 13:02
arekkusu8228-Sep-07 13:02 
GeneralRelease only Pin
Mike webb23-Sep-07 23:52
Mike webb23-Sep-07 23:52 
GeneralRe: Release only Pin
Mystify28-Sep-07 1:06
Mystify28-Sep-07 1:06 
GeneralRe: Release only Pin
Mike webb28-Sep-07 2:32
Mike webb28-Sep-07 2:32 
GeneralRe: Release only Pin
Member 193714023-Feb-09 14:07
Member 193714023-Feb-09 14:07 
HI Mike, will you be able to provide the code sample for this tool you created. I need to do the same and looking for a solution.
Thanks
GeneralGetting build number from environment variable. Pin
Bjornar8-Aug-07 23:47
Bjornar8-Aug-07 23:47 
QuestionCustom MSBuild Task work for Rebuild, but not Build target. Pin
T_C16-Aug-07 20:16
T_C16-Aug-07 20:16 
GeneralSource Safe integration Pin
Deveng7-May-07 10:08
Deveng7-May-07 10:08 
AnswerRe: Source Safe integration Pin
michael_burgess17-Sep-07 20:09
michael_burgess17-Sep-07 20:09 
GeneralWeb App Versioning Pin
JRBlack1026-Mar-07 8:45
JRBlack1026-Mar-07 8:45 
GeneralRe: Web App Versioning Pin
Mystify28-Sep-07 1:08
Mystify28-Sep-07 1:08 
QuestionMicrosoft.Build error Pin
may21517-Jan-07 21:30
may21517-Jan-07 21:30 
AnswerRe: Microsoft.Build error Pin
Mystify18-Jan-07 1:29
Mystify18-Jan-07 1:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.