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:
Imports System
Imports Microsoft.Build.Framework
Imports Microsoft.Build.Utilities
Namespace BuildTasks
Public Class IncrementBuildNumber
Inherits Task
Dim m_AssemblyFileLocation As String
Public Overrides Function _
Execute() As Boolean
Try
Return IncrementVersion()
Catch ex As Exception
Log.LogError(ex.Message)
Return False
End Try
End Function
<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
m_AssemblyFileLocation & _
vbNewLine & _
vbNewLine & _
"Copy path to clipboard?", _
MsgBoxStyle.YesNo) = _
MsgBoxResult.Yes Then
If IO.File.Exists(m_AssemblyFileLocation) Then
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
Try
FileData = _
IO.File.ReadAllLines(m_AssemblyFileLocation)
" lines from " & m_AssemblyFileLocation)
If FileData.Length = 0 Then Exit Function
For i = 0 To FileData.Length - 1
s = FileData(i)
If s.Length > 2 Then
If Not s.Substring(0, 1) = "'" _
And Not s.Substring(0, 2) = "//" Then
If s.Contains("AssemblyVersion") _
Or s.Contains("AssemblyFileVersion") Then
Version = _
Microsoft.VisualBasic.Right(s, _
s.Length - s.IndexOf(Chr(34)) - 1)
Version = _
Microsoft.VisualBasic.Left(Version, _
Version.IndexOf(Chr(34)))
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
If ResetRevision Then
Revision = 1
FileData(i) = _
FileData(i).Replace(Version, _
Major & "." & Minor & "." & _
BuildNumber & "." & Revision)
End If
End If
End If
Next
IO.File.WriteAllLines(m_AssemblyFileLocation, _
FileData)
Catch ex As Exception
MsgBox("ERROR! " & ex.Message, "Build Tasks")
Log.LogError(ex.Message)
Return False
End Try
End If
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.
<UsingTask TaskName="BuildTasks.IncrementBuildNumber"
AssemblyFile="BuildTask.dll" />
An example of one of my project files would look like this, then:
="1.0" ="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:
<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.:
<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.