在 stackoverflow 看到一篇增加版本號的討論,其中使用 TextTransform.exe 將樣板建立成有新的版本號的 assemblyinfo.cs。裡面的步驟需要的依序建立 assemblyinfo.tt,然後在專案的建置屬性設置 prebuild。
如果每個新建專案都要加入 assemblyinfo.tt 和設定 Prebuild 又有點麻煩,所以我直接修改 Visual Studio 的 ProjectTemplates 達到每次新增專案,就已經是配置好的項目。
樣板路徑 是 Visual studio 安裝路徑
%ProgramFiles%\Microsoft Visual studio 9.0\Common7\Ide\ProjectTemplates
%ProgramFiles%\Microsoft Visual studio 9.0\Common7\Ide\ProjectTemplatesCache
在使用時會從 ProjectTemplatesCache 產生專案,所以可以只改 ProjectTemplatesCache
增加編譯時自動增加版本號的樣板,例如 Windows Application
D:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Windows\1028\WindowsApplication
1. 覆製 assemblyinfo.cs -> assemblyinfo.tt
=====assemblyinfo.tt=====================================
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
int incRevision = 1;
int incBuild = 1;
try { incRevision = Convert.ToInt32(this.Host.ResolveParameterValue("","","Debug"));} catch( Exception ) { incBuild=0; }
try { incBuild = Convert.ToInt32(this.Host.ResolveParameterValue("","","Release")); } catch( Exception ) { incRevision=0; }
try {
string currentDirectory = Path.GetDirectoryName(Host.TemplateFile);
string assemblyInfo = File.ReadAllText(Path.Combine(currentDirectory,"AssemblyInfo.cs"));
Regex pattern = new Regex("AssemblyVersion\\(\"\\d+\\.\\d+\\.(?<revision>\\d+)\\.(?<build>\\d+)\"\\)");
MatchCollection matches = pattern.Matches(assemblyInfo);
revision = Convert.ToInt32(matches[0].Groups["revision"].Value) + incRevision;
build = Convert.ToInt32(matches[0].Groups["build"].Value) + incBuild;
}
catch( Exception ) { }
#>
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 組件的一般資訊是由下列的屬性集控制。
// 變更這些屬性的值即可修改組件的相關
// 資訊。
[assembly: AssemblyTitle("$projectname$")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("$registeredorganization$")]
[assembly: AssemblyProduct("$projectname$")]
[assembly: AssemblyCopyright("Copyright © $registeredorganization$ $year$")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 將 ComVisible 設定為 false 會使得這個組件中的型別
// 對 COM 元件而言為不可見。如果您需要從 COM 存取這個組件中
// 的型別,請在該型別上將 ComVisible 屬性設定為 true。
[assembly: ComVisible(false)]
// 下列 GUID 為專案公開 (Expose) 至 COM 時所要使用的 typelib ID
[assembly: Guid("$guid1$")]
// 組件的版本資訊是由下列四項值構成:
//
// 主要版本
// 次要版本
// 組建編號
// 修訂編號
//
// 您可以指定所有的值,也可以依照以下的方式,使用 '*' 將組建和修訂編號
// 指定為預設值:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.<#= this.revision #>.<#= this.build #>")]
[assembly: AssemblyFileVersion("1.0.<#= this.revision #>.<#= this.build #>")]
<#+
int revision = 0;
int build = 0;
#>
3. windowsapplication.csproj 修改
<#@ output extension=".cs" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
int incRevision = 1;
int incBuild = 1;
try { incRevision = Convert.ToInt32(this.Host.ResolveParameterValue("","","Debug"));} catch( Exception ) { incBuild=0; }
try { incBuild = Convert.ToInt32(this.Host.ResolveParameterValue("","","Release")); } catch( Exception ) { incRevision=0; }
try {
string currentDirectory = Path.GetDirectoryName(Host.TemplateFile);
string assemblyInfo = File.ReadAllText(Path.Combine(currentDirectory,"AssemblyInfo.cs"));
Regex pattern = new Regex("AssemblyVersion\\(\"\\d+\\.\\d+\\.(?<revision>\\d+)\\.(?<build>\\d+)\"\\)");
MatchCollection matches = pattern.Matches(assemblyInfo);
revision = Convert.ToInt32(matches[0].Groups["revision"].Value) + incRevision;
build = Convert.ToInt32(matches[0].Groups["build"].Value) + incBuild;
}
catch( Exception ) { }
#>
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 組件的一般資訊是由下列的屬性集控制。
// 變更這些屬性的值即可修改組件的相關
// 資訊。
[assembly: AssemblyTitle("$projectname$")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("$registeredorganization$")]
[assembly: AssemblyProduct("$projectname$")]
[assembly: AssemblyCopyright("Copyright © $registeredorganization$ $year$")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 將 ComVisible 設定為 false 會使得這個組件中的型別
// 對 COM 元件而言為不可見。如果您需要從 COM 存取這個組件中
// 的型別,請在該型別上將 ComVisible 屬性設定為 true。
[assembly: ComVisible(false)]
// 下列 GUID 為專案公開 (Expose) 至 COM 時所要使用的 typelib ID
[assembly: Guid("$guid1$")]
// 組件的版本資訊是由下列四項值構成:
//
// 主要版本
// 次要版本
// 組建編號
// 修訂編號
//
// 您可以指定所有的值,也可以依照以下的方式,使用 '*' 將組建和修訂編號
// 指定為預設值:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.<#= this.revision #>.<#= this.build #>")]
[assembly: AssemblyFileVersion("1.0.<#= this.revision #>.<#= this.build #>")]
<#+
int revision = 0;
int build = 0;
#>
=====assemblyinfo.tt End=====================================
2. csWindowsAplication.vstemplate 加入內容 <ProjectItem ReplaceParameters="true" TargetFileName="Properties\AssemblyInfo.tt">AssemblyInfo.tt</ProjectItem>
<VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateContent>
<Project File="WindowsApplication.csproj" ReplaceParameters="true">
<ProjectItem ReplaceParameters="true" TargetFileName="Properties\AssemblyInfo.tt">AssemblyInfo.tt</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="Properties\AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
<Project File="WindowsApplication.csproj" ReplaceParameters="true">
<ProjectItem ReplaceParameters="true" TargetFileName="Properties\AssemblyInfo.tt">AssemblyInfo.tt</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="Properties\AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
</Project>
</TemplateContent>
</VSTemplate
</TemplateContent>
</VSTemplate
3.1 找到 <Compile Include="Properties\AssemblyInfo.cs"/> 用以下內容置換
<None Include="Properties\AssemblyInfo.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>AssemblyInfo.cs</LastGenOutput>
</None>
<Compile Include="Properties\AssemblyInfo.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>AssemblyInfo.tt</DependentUpon>
</Compile>
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>AssemblyInfo.cs</LastGenOutput>
</None>
<Compile Include="Properties\AssemblyInfo.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>AssemblyInfo.tt</DependentUpon>
</Compile>
3.2 找到 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 這行下面加入以下內容,讓msbuild 時能透過樣板重建 assemblyinfo.cs
<PropertyGroup>
<PreBuildEvent>"%25CommonProgramFiles(x86)%25\microsoft shared\TextTemplating\10.0\TextTransform.exe" -a !!$(ConfigurationName)!1 "$(ProjectDir)Properties\AssemblyInfo.tt"</PreBuildEvent>
</PropertyGroup>
<PreBuildEvent>"%25CommonProgramFiles(x86)%25\microsoft shared\TextTemplating\10.0\TextTransform.exe" -a !!$(ConfigurationName)!1 "$(ProjectDir)Properties\AssemblyInfo.tt"</PreBuildEvent>
</PropertyGroup>