T4 でクラスやプロパティを自動生成する

Text Template Transformation Toolkit (T4) はテンプレート エンジンの一つで、主に Visual Studio で使われているものです。
これを使うと、ソースコードやデータの集合などのファイルを自動生成できます。

今回は例として、次のような Markdown を記述したら、
それに対応するクラスやプロパティを C# のソースコードとして生成することを考えます。

この Markdown の仕様を次のように定めます。

  • 空行は無視
  • 箇条書きでない行がクラス名
  • その下に続く箇条書きはプロパティ
    • 「- Type PropertyName」の形式
    • プロパティ名が省略された場合は、型名と同じ
  • クラス名およびプロパティ名は、PascalCase, camelCase のどちらを指定してもよい

以下では、このような .md ファイルを入力として、
プロパティおよびコンストラクターを持つ部分クラスを .cs ファイルに出力するように T4 で実装していきます。

まず、プロジェクトに上記の .md ファイルを追加しておきます。
そしてプロジェクトに「テキスト テンプレート (.tt)」 を追加します。

Add New Item

追加された .tt ファイルを、仕様に従って次のように実装します。

注意点は以下の通りです。

  • 初期状態では出力の拡張子が .txt になっているため、.cs に変更する
  • プロジェクト内のファイルのパスを取得するには、hostspecific="true" を指定して Host.ResolvePath メソッドを使う
  • <#= #> :テキストの出力
  • <# #> :コードを書ける、変数を使える
  • <#+ #> :メソッド、クラスなどを定義できる

.tt ファイルを保存したときに処理が実行されます。
または、.tt ファイルを右クリックして [カスタム ツールの実行] を選択すれば実行されます。

Run Custom Tool

これで、以下のように RecordTypes.cs が生成されます。

 

作成したサンプル

テストしたバージョン

  • Visual Studio 2017

参照

広告
カテゴリー: ツール. タグ: , . Leave a Comment »

.NET Core 向けビルド スクリプト

ビルド用 PowerShell スクリプトの Build Release (GitHub) を .NET Framework プロジェクト形式向けに提供していましたが、
今回は .NET Core プロジェクト形式向けのビルドツールを追加しました。

ツールの内容:

(1) Version 1up

アセンブリのバージョン (x.y.z の z の部分) を 1 だけ増加させます。
.NET Core プロジェクト形式では、プロジェクト ファイル (.csproj) でバージョンを書き換えます。

(2) Zip Release

プロジェクトを Release でビルドして、ZIP ファイルを作成します。
ビルド前にアセンブリのバージョンを増加させます。

(3) NuGet Packup

プロジェクトを Release でビルドして、NuGet パッケージを作成します。
ビルド前にアセンブリのバージョンを増加させます。

これらのツール (PowerShell スクリプト) を使う方法としては、Visual Studio の「外部ツール」に登録するのが便利だと思います。
前回にビルド用のスクリプトを Visual Studio の外部ツールに登録する方法について書きましたが、
.NET Core 版の手順も改めて以下に書いておきます。

セットアップ

Build-Release/Downloads (GitHub) からツールの最新版をダウンロードして任意のフォルダーに展開します。

Explorer

Visual Studio のメニューで [ツール] – [外部ツール] を選択して各スクリプトを追加していきます。

  • タイトル: 任意
  • コマンド: powershell.exe
  • 引数: -ExecutionPolicy Unrestricted "C:\scripts_folder\KTools.xxx.ps1"
  • 初期ディレクトリ: $(ProjectDir)
    • 右の ▶ ボタンで選択できる
    • Version 1up では $(SolutionDir) でもよい
  • 出力ウィンドウを使用: オン

External Tools

 

プロジェクトの作成

.NET Core 向けのプロジェクト テンプレートを選択してプロジェクトを作成します。

New Project

.NET Framework プロジェクトではバージョン番号などを AssemblyInfo.cs に記述しますが、
.NET Core プロジェクトではプロジェクト ファイル (.csproj) に記述します。
初期状態ではバージョンが設定されていない (その場合は 1.0.0 と判定される) ため、
プロジェクトのプロパティで [パッケージ バージョン] の値を設定しておきます。

Project Property

上記の設定をして保存すると、.csproj ファイルの <Version> に反映されます。

.csproj

なお、.NET Core のプロジェクト形式でも、

<TargetFramework>net45</TargetFramework>

のようにすれば .NET Framework をターゲットにすることができます。
詳細は .NET Core と .NET Standard を参照してください。

 

ツールの実行:

(1) Version 1up

対象のプロジェクト内のファイルを開いた状態で、メニューからスクリプトを選択すると実行されます。

External Tools Menu

実行すると、ログが Visual Studio に出力されます。

Version 1up Output

 

(2) Zip Release

同様に、メニューから Zip Release を実行します。
zip フォルダーに ZIP ファイルが作成されます。

Zip Release

 

(3) NuGet Packup

クラス ライブラリ プロジェクトを対象に NuGet Packup を実行します。
pkg フォルダーに NuGet パッケージが作成されます。

NuGet Packup

 

注意点

  • .NET Framework プロジェクト形式向けには NuGet 経由でプロジェクトに PowerShell スクリプトを追加する
    方法 (KTools.ZipRelease) も提供していますが、.NET Core プロジェクト形式では NuGet で同様の方法で追加できませんでした。

 

前回: ビルド用のスクリプトを Visual Studio の外部ツールに登録する

テスト済バージョン
Visual Studio 2017

参照
Build Release (GitHub)
外部ツールの管理
.nuspec File Reference for NuGet

カテゴリー: ALM, ツール. タグ: , . 3 Comments »

ビルド用のスクリプトを Visual Studio の外部ツールに登録する

以前にビルドして ZIP にする PowerShell スクリプトを作成しましたが、
そのときはプロジェクトごとに NuGet でインストールする方法を前提としていました。
今回は各スクリプトを Visual Studio の外部ツールとして登録する方法も便利だとわかったため、その利用手順を紹介します。

設定手順:

  • Build-Release/Downloads (GitHub) から最新版をダウンロードして、任意のフォルダーに PowerShell スクリプトを展開する
  • Visual Studio のメニューで [ツール] – [外部ツール] を選択して各スクリプトを追加する
    • タイトル: 任意
    • コマンド: powershell.exe
    • 引数: -ExecutionPolicy Unrestricted "C:\scripts_folder\KTools.xxx.ps1"
    • 初期ディレクトリ: $(ProjectDir)
      • 右の ▶ ボタンで選択できる
      • KTools.VersionIncrement.ps1 は $(SolutionDir) でもよい
    • 出力ウィンドウを使用: オン

ExternalTools

 

以上の設定で、「プロジェクト フォルダー上で PowerShell スクリプトを実行する」ためのメニューが
Visual Studio の [ツール] メニューに追加されました。
実行するには、対象のプロジェクトのファイルを開いているときにメニューからそれらを選択します。

ExternalTools-Menu

[出力ウィンドウを使用] がオンに設定されていると、ログが Visual Studio に出力されます。

ExternalTools-Output

ExternalTools-Zip

 

このように Visual Studio の外部ツールを利用することで、
バージョンアップ、Release ビルド、ZIP 作成が Visual Studio から簡単にできるようになりました。

このツールは .NET Framework プロジェクト形式向けに提供していますが、
次回は .NET Core プロジェクト形式向けのツールを追加します。

次回: .NET Core 向けビルド スクリプト

テスト済バージョン
Visual Studio 2017

参照
Build Release (GitHub)
外部ツールの管理
Visual Studioの外部ツール機能を活用してみよう
ビルドして ZIP にする PowerShell スクリプト

カテゴリー: ALM, ツール. タグ: , . 3 Comments »

.NET Core と .NET Standard

.NET Core の登場以降、Visual Studio で新しいプロジェクトを作成しようとすると、
従来の .NET Framework のほかに .NET Core と .NET Standard 向けのプロジェクト テンプレートが現れます。

NewProject

それぞれのプロジェクトにおけるアセンブリの参照可否をまとめると次のようになります。

  • .NET Framework 向けプロジェクト
    • .NET Framework アセンブリを参照可能
    • .NET Core アセンブリを参照不可
    • .NET Standard アセンブリを参照可能
  • .NET Core 向けプロジェクト
    • .NET Framework アセンブリを参照不可
    • .NET Core アセンブリを参照可能
    • .NET Standard アセンブリを参照可能

.NET Framework と .NET Core はランタイムが異なるため、
両方に対応するクロスプラットフォームのクラス ライブラリを作成するには .NET Standard をターゲットにします。
なお、.NET Standard 2.0 アセンブリは .NET Framework 4.6.1 以上で参照可能です。

.NET Core および .NET Standard のプロジェクト テンプレートには、次の特徴があります。

  • .csproj ファイルの記述が簡略化されている
    • アセンブリ情報は .csproj ファイルに含まれ、AssemblyInfo.cs は不要
  • NuGet パッケージを簡単に作成できる
    • ビルド時に作成するように設定できる

クラス ライブラリの .csproj ファイルの内容は次のようになっています。


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

</Project>


TargetFramework を TargetFrameworks に変更すれば、対象のフレームワークをセミコロン区切りで複数指定できます。
ここで指定する netstandard2.0net40 は、Target Framework Moniker と呼ばれます。

<TargetFrameworks>netstandard2.0;net40</TargetFrameworks>

これで複数のフレームワークを対象にしたアセンブリを一度にビルドできます。

TargetFrameworks

.NET Framework 向けのみのアセンブリを作成したい場合であっても、
.NET Core 向けのテンプレートから作成して TargetFramework を変更する方法が有効です。

次に、OutputTypeExe を指定すればコンソール アプリになります (指定がなければクラス ライブラリ)。

<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;net45</TargetFrameworks>

コンソール アプリをビルドすると、.NET Framework 向けでは .exe が生成されますが、.NET Core 向けでは .dll となります。
(自己完結型デプロイにより、各プラットフォーム向けの実行可能ファイルを生成することもできます。ただし 60MB 前後になります。)

NetCoreConsole

DLL の状態の .NET Core 向けアプリを実行するには、dotnet コマンドを実行します。

dotnet ConsoleApp1.dll

その他の注意点

  • 例えば System.Security.Cryptography 名前空間は .NET Standard で利用可能ですが、
    .NET Framework と .NET Core ではクラス構成に差異があります。
    ビルドできても実行時にエラーとなることもあります (HashAlgorithm.Create メソッドなど)。

 

次回: dotnet コマンドによるビルド

作成したサンプル

バージョン情報

  • Visual Studio 2017
  • .NET Core 2.0

参照

ビルドして ZIP にする PowerShell スクリプト

以前に .NET ビルド小技集 (4) という記事を書き、
PowerShell でバージョンをインクリメントしてビルドする方法を紹介しました。
今回は、そのツールを改良したうえで NuGet で公開しました。

Visual Studio のプロジェクトに対して、NuGet で KTools.ZipRelease をインストールすると、
次の PowerShell ファイルがプロジェクトに追加されます。

  • KTools.VersionIncrement.ps1
  • KTools.ZipRelease.ps1

image

エクスプローラー上で PowerShell スクリプトを実行できます。

image

KTools.ZipRelease.ps1 により、以下の処理が実行されます。

  • バージョン番号のインクリメント (KTools.VersionIncrement.ps1 の呼び出し)
  • MSBuild.exe を利用して Release ビルド
  • ビルドの結果を ZIP ファイルにする
    • ファイル名は「AssemblyName-x.y.z.zip」の形式
    • 既定ではプロジェクト フォルダーの下の「zip」フォルダーに作成される

image

 

KTools.VersionIncrement.ps1 により、AssemblyInfo.cs 内の
AssemblyVersion 属性および AssemblyFileVersion 属性の値のビルド番号を 1 だけ増加させています。
例えば、1.0.2.0 が 1.0.3.0 に、1.0.2 が 1.0.3 に、1.0.2-alpha が 1.0.3-alpha に変わります。

ちなみに、バージョン番号は .exe および .dll ファイルのプロパティに反映されます。

image

PowerShell スクリプトのため、各自の要件に合わせてカスタマイズできるでしょう。
また、バージョン番号のインクリメントについては、
KTools.VersionIncrement として単独でインストールして使うことができます。

 

技術的には、以下の特徴が挙げられます。
ソースコードは Build Release (GitHub) にあります。

  • PowerShell の中で C# を利用
  • 値を変更する処理で正規表現を利用
  • .csproj ファイルからの値の読み込みに XPath を利用
  • MSBuild.exe のパスを探索 (たいへん)
    • .NET Framework 付属の MSBuild より Visual Studio 付属の MSBuild を優先

 

追記: ビルド用のスクリプトを Visual Studio の「外部ツール」に登録すると便利です。
また、.NET Core プロジェクト形式向けのビルド スクリプトも追加しました。

作成したツール
Build Release (GitHub)

参照
.NET ビルド小技集 (4)
.NET Framework の正規表現
.nuspec リファレンス
NuGet Package Version Reference

.NET ビルド小技集 (2)

前回の .NET ビルド小技集 (1) では、プロジェクトのビルド イベントを利用しました。
今回はビルド イベントで ZIP ファイルを作成する方法についてです。

 

ZIP ファイルを作成する

前回説明したファイルのコピーに加えて、ビルドにより出力された実行ファイル一式を圧縮して ZIP ファイルにします。
PowerShell では .NET のライブラリを利用することができるため、
PowerShell スクリプトで ZIP ファイルを作成することにします。
(PowerShell には圧縮のための Compress-Archive Cmdlet があったりもしますが。)

まず、ZipFile.CreateFromDirectory メソッドをラップしたスクリプトを用意します。
引数は、アセンブリのディレクトリと ZIP ファイルのパスです。

そして、前回のプロジェクトのビルド イベントでこのスクリプトを呼び出します。

cd $(ProjectDir)
xcopy Data $(OutDir)Data /D/E/C/I/H/Y
powershell -ExecutionPolicy Unrestricted ..\Tools\CreateZip.ps1 $(OutDir) ..\Downloads\$(TargetName).zip

これで、ビルドのたびに ZIP ファイルが作成されます。

image

 

ちなみに、PowerShell では C# のコードを埋め込むことができます。
次のようにしても同様の結果が得られます。

 

ZIP ファイルの名前にバージョンを含める

さらに、ZIP ファイルの名前を、App1-1.0.0.zip のようにバージョン番号が含まれるようにしてみましょう。
バージョン番号として、AssemblyInfo.cs の AssemblyFileVersion 属性に指定された値を取得します。

先ほどの CreateZip.ps1 を拡張して、
対象のアセンブリから AssemblyFileVersion 属性を取得して、
ZIP ファイルの名前が App1-1.0.0.zip の形式になるように組み立てます。
このスクリプトの引数は、アセンブリのパスと出力先のディレクトリとしています。

あとは、プロジェクトのビルド イベントでこのスクリプトを呼び出します。

cd $(ProjectDir)
xcopy Data $(OutDir)Data /D/E/C/I/H/Y
powershell -ExecutionPolicy Unrestricted ..\Tools\CreateZipForAssembly.ps1 $(TargetPath) ..\Downloads

AssemblyFileVersion 属性には、「1.0.1-Alpha」のように任意の文字列を指定できるようです。
(ただし、AssemblyVersion 属性は数値または * でなければビルド エラーになります。)

image

実行結果:

image

 

次回は、ビルド自体を PowerShell で実行する方法についてです。

前回: .NET ビルド小技集 (1)
次回: .NET ビルド小技集 (3)

作成したサンプル
BuildSample (GitHub)

バージョン情報
Visual Studio 2013

参照
ZipFile.CreateFromDirectory メソッド

Add-Type
PowerShell の Add-Type と [Reflection.Assembly]
PowerShellスクリプト内でC#コードを書いて使う

Compress-Archive
PowerShell v5 の新機能紹介 – Zipファイルの操作が可能に

カテゴリー: ALM, ツール. タグ: , . 2 Comments »

.NET ビルド小技集 (1)

.NET アプリケーション開発のビルドに関する小技を集めました。
以下の内容の実現方法について取り扱います。

  • ビルド時にファイルをコピーする
  • ZIP ファイルを作成する
  • ZIP ファイルの名前にバージョンを含める
  • PowerShell でビルドする
  • PowerShell でバージョンをインクリメントしてビルドする

追記: ビルド用のスクリプトを Visual Studio の「外部ツール」に登録すると便利です。
また、.NET Core プロジェクト形式向けのビルド スクリプトも追加しました。

 

ビルド時にファイルをコピーする

.NET アプリケーションをビルドすると、
プロジェクト フォルダーの下の bin\Debug や bin\Release に実行ファイルが出力されます。
このとき同時に、画像、動画、データなどのコンテンツ ファイルをコピーする方法を紹介します。
(サイズの小さい画像ファイルであればアセンブリ内のリソースとして埋め込んで使いますが。)

よくある方法としては、コンテンツ ファイルをプロジェクトに含めて、プロパティで [出力ディレクトリにコピー] の項目を設定します。
ただしこれだと、ファイルごとに設定しなければならないという欠点があります。

imageimage

 

この欠点を回避するには、プロジェクトのビルド イベントを利用するとよいでしょう。
プロジェクトのプロパティを開き、[ビルド イベント] を選択します。
この画面で、ビルド時に実行するコマンド ラインを指定できます。

ファイルをコピーするには copy、フォルダーをコピーするには xcopy を利用します。

xcopy $(ProjectDir)Data $(TargetDir)Data /D/E/C/I/H/Y

image

$(ProjectDir) などの形式の文字列はマクロと呼ばれるもので、
ソリューションやプロジェクトにとっての特別な文字列を扱うことができます。
[ビルド後の編集] をクリックするとエディターが開きます。
ここではマクロの実際の値を確認しながら自動で挿入できます。

image

 

上記で使用した xcopy の各オプションの説明も挙げておきます。

  • /D コピー元の日付がコピー先の日付より新しいファイルだけをコピーします。
  • /E ディレクトリまたはサブディレクトリが空であってもコピーします。"/S /E" と同じ意味です。
  • /C エラーが発生してもコピーを続けます。
  • /I 指定されたコピー先が存在しない場合、コピー先をディレクトリとしてコピーします。
  • /H 隠しファイルやシステム ファイルもコピーします。
  • /Y 既存のファイルを上書きする前に確認のメッセージを表示しません。

 

このように設定してビルドを実行すれば、出力ディレクトリにコンテンツ ファイルがコピーされます。

image

 

なお、ビルド イベントでコマンド ラインが実行されるときの作業ディレクトリは、
$(TargetDir)、つまり bin\Debug や bin\Release などの出力ディレクトリです。
複数のコマンドを実行する場合など、相対パスにしたほうがわかりやすくなるときは、

cd $(ProjectDir)
xcopy Data $(OutDir)Data /D/E/C/I/H/Y

のように作業ディレクトリを設定するとよいでしょう。

次回は、ビルド時に ZIP ファイルを作成する方法についてです。

次回: .NET ビルド小技集 (2)

作成したサンプル
BuildSample (GitHub)

バージョン情報
Visual Studio 2013

参照
Copy
Xcopy

カテゴリー: ALM, ツール. タグ: . 1 Comment »