1. kounoike

    No comment

    kounoike
Changes in body
Source | HTML | Preview
@@ -1,77 +1,81 @@
# はじめに
ソリューションの中にたくさんのプロジェクトがあって、それを全部AssemblyVersion.csでバージョン指定してあると、バージョン番号の変更が大変ですよね。
ちょっと別ツールでそういう変更をやってくれるツールを作ったりもしていたのですが、Visual Studioの標準機能でもできるらしい。ということでメモを兼ねて投稿。
# T4 テンプレート
T4 というテンプレートが Visual Studio には組み込まれているので、それを使うとビルド前に自動的にファイルのテンプレート展開をやってくれる。
T4 テンプレートの適用は簡単で、プロジェクトに新しい項目の追加で「テキストテンプレート」を選べば良い。
デフォルトではこんなファイルが出来上がる。名前は AssemblyInfo.tt にしておく。この段階ではプロジェクトの直下に作る。
```text:T4
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".txt" #>
```
まずは output extension の項目を .cs に変更して、.cs ファイルを生成するようにしよう。ついでに hostspecific を true にして Visual Studio のファイルパスにアクセスできるようにしておく。
で、この後の内容にもともとの AssemblyInfo.cs をコピーしてくる。コピーしたら元の AssemblyInfo.cs はいらなくなるので削除する(そうしないと、Properties の下に移動できない)。
削除が終わったら、プロジェクトの直下にあった AssembyInfo.tt を Properties の下に移動する。
このままではまだ AssemblyInfo.tt を手書きで書き直さないといけないので、共通のファイルを読みにいくように変更しよう。
ソリューションの直下に以下のようなXMLファイルを作る。あとでGetElementByIdで一個ずつ取るために id 属性も指定しておく。
```xml:Version.xml
<?xml version="1.0" encoding="utf-8"?>
<config>
<MajorVersion id="MajorVersion">1</MajorVersion>
<MinorVersion id="MinorVersion">2</MinorVersion>
<BuildNumber id="BuildNumber">0</BuildNumber>
<Revision id="Revision">0</Revision>
</config>
```
このファイルを読み込むように AssemblyInfo.tt にコードを書こう。
まずは System.Xml の using に相当するコードを書く。
```
<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System.Xml" #>
```
一行目が参照設定の追加に相当するディレクティブで、二行目が using 相当。
で、これを使って XML ファイルの中身を読み出そう。
```csharp
<#
string file = this.Host.ResolvePath(@"..\..\Version.xml");
XmlDocument xdoc = new XmlDocument();
xdoc.Load(file);
string majorVersion = xdoc.SelectSingleNode("config/MajorVersion").InnerText;
string minorVersion = xdoc.SelectSingleNode("config/MinorVersion").InnerText;
string buildNumber = xdoc.SelectSingleNode("config/BuildNumber").InnerText;
string revision = xdoc.SelectSingleNode("config/Revision").InnerText;
string verString = String.Format("{0}.{1}.{2}.{3}", majorVersion, minorVersion, buildNumber, revision);
#>
```
この値を使って AssemblyVerion, AssemblyFileVersion を書き換えよう。
```
[assembly: AssemblyVersion("<#= verString #>")]
[assembly: AssemblyFileVersion("<#= verString #>")]
```
# 注意
Version.xml を開いたままビルドすると「~のスキーマ情報が見つかりませんでした」というInfoレベルのメッセージが出る。これは、単にファイルを閉じてビルドするだけで消えるらしい。なんだそりゃという気もするが仕方ない・・・
+
+# Jenkins との連携
+Jenkins (というか MSBuild)で自動的にテンプレート変換を実行するには骨が折れる様子。
+http://mediaingenuity.github.io/2013/12/18/text-template-transformation-t4-integration-msbuild.html このページを参考にすればいけそうだが・・・?