LoginSignup
14
14

More than 5 years have passed since last update.

VisualStudio の T4 で AssemblyInfo.cs を一括置換する

Last updated at Posted at 2015-06-28

はじめに

ソリューションの中にたくさんのプロジェクトがあって、それを全部AssemblyVersion.csでバージョン指定してあると、バージョン番号の変更が大変ですよね。

ちょっと別ツールでそういう変更をやってくれるツールを作ったりもしていたのですが、Visual Studioの標準機能でもできるらしい。ということでメモを兼ねて投稿。

T4 テンプレート

T4 というテンプレートが Visual Studio には組み込まれているので、それを使うとビルド前に自動的にファイルのテンプレート展開をやってくれる。

T4 テンプレートの適用は簡単で、プロジェクトに新しい項目の追加で「テキストテンプレート」を選べば良い。

デフォルトではこんなファイルが出来上がる。名前は AssemblyInfo.tt にしておく。この段階ではプロジェクトの直下に作る。

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 を手書きで書き直さないといけないので、共通のファイルを読みにいくように変更しよう。

ソリューションの直下に以下のようなVersion.t4ファイルを作る。

<#
    int majorVersion = 1;
    int minorVersion = 2;
    int buildNumber = 1;
    int revision = 1;
#>

このファイルを読み込むように AssemblyInfo.tt にコードを書こう。
include ディレクティブを書けばよい。

<#@ include file="..\..\Version.t4" #>

このバージョン番号を使ってバージョン文字列を生成しよう。

<#
    string verString = String.Format("{0}.{1}.{2}.{3}", majorVersion, minorVersion, buildNumber, revision);
#>

で、この値を使って AssemblyVerion, AssemblyFileVersion を書き換えよう。

[assembly: AssemblyVersion("<#= verString #>")]
[assembly: AssemblyFileVersion("<#= verString #>")]

バージョンを変えたときに自動的にT4変換を実行させる

このままだと、.ttファイルを編集しないと Visual Studio は「変えなくて良いんだな~」と判断して、AssemblyInfo.cs を変更してくれない。そこで、拡張機能の「AutoT4」をインストールする。インストールすると設定不要で、いつでも.tt を変換してくれるようになる。

Jenkins との連携

Jenkins (というか MSBuild)で自動的にテンプレート変換を実行するには骨が折れる様子。
http://mediaingenuity.github.io/2013/12/18/text-template-transformation-t4-integration-msbuild.html このページを参考にすればいけそうだが・・・?

以下を入れた上でちょっと色々いじるらしい。
Visual Studio 2013 SDK
https://www.microsoft.com/en-us/download/details.aspx?id=40758

Modeling SDK for Microsoft Visual Studio 2013
https://www.microsoft.com/en-us/download/details.aspx?id=40754

2010はこれ
Visual Studio 2010 SDK
https://www.microsoft.com/en-us/download/details.aspx?id=2680

2010SP1だとこれ。SP1当ててると上のは動かない。
http://www.microsoft.com/en-us/download/details.aspx?id=21835

Microsoft Visual Studio 2010 Visualization & Modeling SDK
https://www.microsoft.com/en-us/download/details.aspx?id=23025

2012も似たような名前なので適当に探して欲しい

.csprojに以下の変更を加える。Projectタグの直下でOKらしい。

<PropertyGroup>
  <TransformOnBuild>True</TransformOnBuild>
  <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets" />

・・・Visual Studio2013で作ってるんだけど、.Net Framework の4.5にしているせいか、$(VisualStudioVersion)がv11.0になるせいでビルドできない・・・

手順@VS2010

まずは適当なプロジェクトを作る。

20150628-175411.png

新しい項目でAssemblyInfo.ttを作る。

20150628-175725.png

できたらProperties以下に移動する。

ソリューション直下に各プロジェクトで共通で使うバージョン番号のテンプレートファイルを作る。
20150628-180448.png

AssemblyInfo.ttを変更する。
20150628-181016.png

・・・と、ここまで書いておいて、Version.t4の変更を検知して.ttの再変換を行ってくれる方法が必要なことに気づいた。

http://www.matthiaseinig.de/2013/05/20/auto-generate-fileversion-for-all-projects-in-a-solution-with-t4/ では、AssemblyInfoを共通のファイルを使うやり方を紹介している。

MSBuildでT4変換できるようにすれば、ビルド前イベントでこうすれば良いようだ。

%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "$(ProjectPath)" /t:TransformAll

残る問題はチーム開発でこれ全部インストールする必要があることかな・・・
試してないけど、Importをこうやれば、VS SDK/Modeling SDKをインストールしていなくてもビルドエラーが出ないようになる・・・かも?

<Import Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v$(VisualStudioVersion)\Microsoft.TextTemplating.targets')" Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v$(VisualStudioVersion)\Microsoft.TextTemplating.targets" />

追記

こんな感じの定義を.csprojの最後に入れればビルド前イベントでMSBuildを使わなくてもOKのようだ。一応、ファイルの有無チェックをしているので、VS SDK、VS Modeling SDKを入れてなくてもエラーは出ないはず・・・多分。

.csproj
  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
    <T4Path>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets</T4Path>
    <T4Path Condition="'$(VisualStudioVersion)' == '10.0'">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v$(VisualStudioVersion)\Microsoft.TextTemplating.targets</T4Path>
  </PropertyGroup>
  <Import Condition="Exists('$(T4Path)')" Project="$(T4Path)" />
  <PropertyGroup Condition="Exists('$(T4Path)')">
    <TranformOnBuild>true</TranformOnBuild>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
    <BuildDependsOn>
      TransformAll;
      BeforeBuild;
      CoreBuild;
      AfterBuild;
    </BuildDependsOn>
  </PropertyGroup>
14
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14