在编译时自动增加 Visual Studio 2005 版本号和修订号






4.67/5 (11投票s)
2006年3月10日
3分钟阅读

285427

974
在编译时自动增加 Visual Studio 2005 版本的构建和修订号。
引言
在 Visual Studio 2005 中,当你构建你的项目时,版本号不会自动增加。烦人吗?我认为是。所以,我开始寻找一种方法来实现它。我在网上找到了一些代码示例,说可以做到,虽然它们在某种程度上确实有效,但它们的效果并不好,甚至根本不起作用。
所以,我开始使用从教程中学到的东西来编写我自己的代码。
使用代码
创建一个 Windows DLL 项目,不必是任何特殊的东西。在默认类中,放入以下内容
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
现在...我们怎么使用它?我的意思是,你现在有一个很棒的 DLL 文件了...但它如何应用于你的项目呢?首先,你需要将你的 DLL 复制到与你的项目文件相同的文件夹中。不要将“解决方案”文件 (.sln) 与你的项目文件 (.vbproj) 混淆,因为它们不是同一回事。
一旦文件被复制,在记事本或其他文本编辑器中打开 .vbproj 文件,这样你就可以看到原始信息了。
在 <project>
标签之后和第一个 <propertygroup>
标签之前,将以下行添加到项目文件中。
<UsingTask TaskName="BuildTasks.IncrementBuildNumber"
AssemblyFile="BuildTask.dll" />
我的一个项目文件的示例如下所示:
<?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>
...
一直向下滚动直到你找到 <Target Name="BeforeBuild">
标签。它可能被注释掉了;取消注释,并在开始和结束标签之间添加以下内容
<IncrementBuildNumber AssemblyFileLocation =
"$(MSBuildProjectDirectory)\My Project\AssemblyInfo.vb">
</IncrementBuildNumber>
注意! 确保你的程序集文件的路径是正确的。如果它不在 "My Projects" 文件夹中,请确保你调整上面的行以说明它在哪里。$(MSBuildProjectDirectory) 变量将被替换为 .vbproj 文件所在的文件夹。因此,如果 assembly.vb 文件位于同一位置,则不要使用任何子文件夹。默认情况下,VS 2005 将其放在 "My Projects" 文件夹中并将其命名为 AssemblyInfo.vb。对于 C#,它是 AssemblyInfo.cs。
这个 DLL 应该适用于 C# 和 VB 项目,而且应该适用于所有 VS 项目...但我只用 C# 和 VB 进行了测试。
保存项目文件,然后在 VS 中打开它。现在,每次你构建项目时,VS 将调用 DLL 中的 IncrementBuildNumber
类并执行其中的代码。代码本身打开你的程序集文件,编辑版本信息,然后保存它。
因为你在 "BeforeBuild
" 部分执行此操作,所以它将在你构建之前完成。很棒吧?
注意:一些项目文件可能没有 <Target Name="BeforeBuild">
标签。如果是这种情况,我通常只是在 <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
行之后添加它们。
例如:
<Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
<Target Name="BeforeBuild">
<IncrementBuildNumber AssemblyFileLocation=
"$(MSBuildProjectDirectory)\AssemblyInfo.vb">
</IncrementBuildNumber>
</Target>
<Target Name="AfterBuild">
</Target>
</Project>
关注点
有时,修订号会跳 2 或 3 个数字。我不知道为什么,我只能假设某些东西没有正确重新加载,或者编译器调用了 DLL 两次或更多次。实际上,我真的不在乎,所以我从未费心去修复它。
此外,如果你打开了项目属性窗口或程序集文件,版本可能不会增加。同样,我没有足够关心这么小的事情,所以没有花时间去尝试修复它。如果你知道原因,请随时告诉我。
历史
- 1.0.0.0 - 初始发布。