|
検索
タグ
ASP.NET
.NET
ASP.NET MVC
F#
Visual Studio
Azure
ASP.NET Core
ライトニングトーク
Plone
Selenium
AJAX
C#
jQuery
JavaScript
SQL Server
ADO.NET Entity Framework
WebMatrix
LINQ
EFCore
TypeScript
カテゴリ
最新の記事
最新のコメント
記事ランキング
最新のトラックバック
以前の記事
2026年 01月 2025年 12月 2025年 11月 2025年 10月 2025年 09月 2025年 08月 2025年 07月 2025年 06月 2025年 05月 2025年 04月 2025年 03月 2025年 02月 2024年 12月 2024年 11月 2024年 10月 2024年 09月 2024年 08月 2024年 04月 2024年 03月 2024年 02月 2024年 01月 2023年 12月 2023年 11月 2023年 10月 2023年 09月 2023年 08月 2023年 07月 2023年 06月 2023年 05月 2023年 04月 2023年 03月 2023年 02月 2023年 01月 2022年 12月 2022年 11月 2022年 10月 2022年 09月 2022年 08月 2022年 07月 2022年 06月 2022年 05月 2022年 04月 2022年 03月 2022年 02月 2022年 01月 2021年 12月 2021年 11月 2021年 10月 2021年 09月 2021年 08月 2021年 07月 2021年 06月 2021年 05月 2021年 04月 2021年 03月 2021年 02月 2021年 01月 2020年 12月 2020年 11月 2020年 10月 2020年 09月 2020年 08月 2020年 07月 2020年 06月 2020年 05月 2020年 04月 2020年 03月 2020年 02月 2020年 01月 2019年 12月 2019年 11月 2019年 10月 2019年 09月 2019年 08月 2019年 07月 2019年 06月 2019年 05月 2019年 04月 2019年 03月 2019年 02月 2019年 01月 2018年 12月 2018年 11月 2018年 10月 2018年 09月 2018年 08月 2018年 07月 2018年 06月 2018年 05月 2018年 04月 2018年 03月 2018年 02月 2018年 01月 2017年 12月 2017年 11月 2017年 10月 2017年 09月 2017年 08月 2017年 07月 2017年 06月 2017年 05月 2017年 04月 2017年 02月 2017年 01月 2016年 12月 2016年 11月 2016年 10月 2016年 09月 2016年 08月 2016年 07月 2016年 06月 2016年 05月 2016年 04月 2016年 03月 2016年 02月 2016年 01月 2015年 12月 2015年 11月 2015年 10月 2015年 09月 2015年 08月 2015年 07月 2015年 05月 2015年 04月 2015年 03月 2015年 02月 2015年 01月 2014年 12月 2014年 11月 2014年 10月 2014年 09月 2014年 08月 2014年 06月 2014年 04月 2014年 03月 2014年 02月 2014年 01月 2013年 12月 2013年 10月 2013年 09月 2013年 08月 2013年 07月 2013年 06月 2013年 05月 2013年 04月 2013年 03月 2013年 02月 2013年 01月 2012年 12月 2012年 11月 2012年 10月 2012年 09月 2012年 08月 2012年 07月 2012年 06月 2012年 05月 2012年 04月 2012年 03月 2012年 02月 2012年 01月 2011年 12月 2011年 11月 2011年 10月 2011年 09月 2011年 08月 2011年 07月 2011年 06月 2011年 05月 2011年 04月 2011年 03月 2011年 02月 2011年 01月 2010年 12月 2010年 11月 2010年 10月 2010年 09月 2010年 08月 2010年 07月 2010年 06月 2010年 05月 2010年 04月 2010年 03月 2010年 02月 2010年 01月 2009年 12月 2009年 10月 2009年 09月 2009年 07月 2009年 06月 2009年 05月 2009年 04月 2009年 03月 2009年 02月 2009年 01月 2008年 12月 2008年 11月 2008年 10月 2008年 09月 2008年 08月 2008年 07月 2008年 06月 2008年 05月 2008年 04月 2008年 03月 2008年 02月 2008年 01月 2007年 12月 2007年 11月 2007年 04月 2007年 03月 2007年 02月 2007年 01月 2006年 11月 2006年 10月 2006年 09月 2006年 08月 2006年 07月 |
2019年 12月 28日
背景Visual Studio や dotnet CLI を使っての、C# による ASP.NET Core アプリ開発における話。 一般的な ASP.NET Core Web アプリケーションは、インターネット上に配置して利用してもらうものだ。 しかし今回の案件はちょっと変わってて、開発した Web アプリを、クライアント台数が数十台程度の閉鎖系のローカルエリアネットワーク内で稼働させることとなった。 (ちなみに、開発した ASP.NET Core Web アプリを稼働させるサーバーPCは Windows OS が採用された) そこで、この案件で開発する ASP.NET Core Web アプリは Windows サービス として開発。 サーバーPC上への最初のセットアップ (Windows サービスとしての登録) を済ませた以後は、xcopy 配置にて簡易にバージョンアップできるようにすることとした。 さてこのような形態だと、開発した ASP.NET Core Web アプリは、Visual Studio 上で開発中ならば「フォルダへ発行」のプロファイルで、ファイルシステム上に成果物を吐き出すようにすることもあろうかと思う。 但し、そうして吐き出されるファイルはかなりの本数に上る。 今回の案件だと、発行された成果物のファイル本数は 184 ファイルに達した。 このように発行された成果物のファイル群を、そのままやりとりするのは無茶がある。 通常は Zip などのアーカイブファイル x 1つにまとめて、そのアーカイブファイルをやりとるすることであろう。 ということで本案件でも実際、発行された成果物のファイル群は、単一の Zip ファイルに固めて持ち運ぶこととなった。 プロジェクトファイルにちょっと書き足して、自動で Zip 化!さて、MSBuild 15.8 からは、「指定されたフォルダ内のファイルを、ディレクトリ構造もそのままに、サブフォルダのファイルも含めてまるっと Zip アーカイブファイルにまとめてしまう」という、"ZipDirectory" タスクが追加されたそうだ。 (そう、それまでは、MSBuild 標準では、Zip アーカイブにまとめる機能は備えられておらず、MSBuild 内で Zip アーカイブを作成するためには MSBuild 拡張を導入する必要があった。) そこで、今回案件では、Visual Studio から「発行」を行なったら、 (発行された成果物のファイル群を収録した) Zip アーカイブファイルを自動で生成するよう、MSBuild スクリプトを仕込むことにしてみた。 MSBuild スクリプトへの仕込みはあっけない。 対象の MSBuild スクリプトファイル = プロジェクトファイル (.csproj) 内に、下記内容のような <Target> ノードを追記するだけだ。 もう少し解説を加えよう。 まず Target 要素の Name 属性を "MakeZipPackage" としているが、このビルドターゲットの名前は重要ではない (衝突しなければ/他のターゲットから依存されていなければ、名前は何でも良い)。 それよりも肝心なのは、AfterTargets 属性で指定している、"AfterPublish" というターゲット名。 すなわちこの指定により、発行が行なわれたあとのタイミングで、上記の「Zip アーカイブを作成する」ターゲットが実行されるようになる仕掛けだ。 あとは MakeDir タスクで、作成する Zip アーカイブファイルの配置先フォルダを作成。 そして最後に満を持して ZipDirectory タスクによって、発行先フォルダの中身を Zip アーカイブファイルにまとめて完了だ。 発行先フォルダのパスは、"$(ProjectDir)$(publishUrl)" で参照できるので、これを "ZipDirectory" タスクの "SourceDirectory" パラメータ (Zip 化対象のフォルダの指定) に渡している。 作成する Zip アーカイブファイルの配置先フォルダは概ねどこでも構わない。 ただしプロジェクトフォルダの直下にするのだけは、ややこしいことになりかねないので止めておくのが良さそうだ。 出力先フォルダ (~/bin) より下のサブフォルダか、あるいはプロジェクトフォルダの兄弟フォルダがいいのではないかと思われる。 上記例では、プロジェクトフォルダの兄弟フォルダのレベルで、"_release" というサブフォルダを作成して、そこを Zip アーカイブファイルの配置先としている。 作成する Zip アーカイブファイルのファイル名も、これまた何でも良い。 上記の例では、ビルドで生成されるアセンブリ (.dll) の名前を "$(AssemblyName)" で参照できるので、、これを Zip アーカイブファイルのファイル名としつつ、さらにパッケージバージョンの指定が "$(Version)" で参照できるので、これを利用して、作成する Zip アーカイブファイルのファイル名の後半にバージョン番号を含めるようにしてみた。 上記例のようなビルドターゲットの MSBuild スクリプトをプロジェクトファイル内に仕込むことで、発行された成果物のファイル群を単一の Zip アーカイブファイルにまとめることができるようになった。 dotnet CLI であれば、下記のように、Release 構成でのビルドを指定しつつ、発行を実行することで、発行成果物ファイル群を収録した Zip アーカイブファイルが生成される。 > dotnet publish -c:Release 複数ある発行プロファイルの内ひとつで Zip 化したい場合もしも、複数の発行プロファイルを使い分けつつ、そのうちのひとつの発行プロファイルで発行する場合のみ、Zip アーカイブファイルを作成したい場合はどうするか。 いくつかやり方はあるのだが、ひとつの方法として、発行プロファイル内に Zip アーカイブファイルを作成する MSBuild スクリプトを仕込むという方法がある。 先の例で記述した <Target Name="MakeZipPackage" ...>...</Target> 要素をいったん .csproj 内からは削除し、代わりに、対象の発行プロファイル、すなわち .pubxml ファイル内に記述するのだ。 発行プロファイル (.pubxml) を指定しての発行の場合は、発行対象のプロジェクトファイル (.csproj) と発行プロファイル (.pubxml) を合成しての MSBuild 実行に等しい。 なので、ある特定の発行プロファイルでのみ何かさせたい場合 (今回の例では Zip アーカイブファイルの作成を行ないたい) は、発行プロファイル (.pubxml) 側に MSBuild スクリプトを仕込むことで実現可能である。 ちなみに、dotnet CLI で、発行プロファイル (.pubxml) を指定しての発行を行なうには、下記のように、"PublishProfile" MSBuild プロパティに、発行プロファイル (.pubxml) へのプロジェクトからの相対パスを設定して実行すればよい。 > dotnet publish -c:Release -p:PublishProfile={ここに.pubxmlへの相対パス}複数ある発行プロファイルの内いくつかで Zip 化したい場合もうちょっと込み入ったケースでは、複数の発行プロファイルがあって、しかしそのうちのひとつだけではなく、いくつかの発行プロファイルで Zip アーカイブファイルを作成したい、というケースも想定される。 ではということで、Zip アーカイブファイルの作成スクリプトを、複数の .pubxml にベタで書いても、まぁ、それで実現はできる。 しかし、できるのではあるが、"DRY 原則" というか、同じスクリプトがコピペで複数のファイルに散在するのは気持ち悪い。 書いていた Zip 作成のスクリプトに手直しが必要になったら、すべての発行プロファイル (.pubxml) で修正作業をするのもどうかと思うわけである。 このようなケースに対処するにはどうするか。 これまたいくつかやり方があるが、一例として、Zip 化する処理はプロジェクトファイル (.csproj) に記載しつつ、「発行後に Zip アーカイブファイルの作成を行なうかどうか」を MSBuild スクリプト内のプロパティでフラグ表現する方法がある。 まず、Zip アーカイブファイルを作成するターゲットは最初の紹介のとおり、(発行プロファイル (.pubxml) ではなく) プロジェクトファイル (.csproj) 内に記述しておく。 但し最初の紹介例に加えて、"Condition" 属性を追加して、「発行後に Zip アーカイブファイルの作成を行なう」フラグが立てられていたときだけ、Zip アーカイブファイル作成ターゲットを有効とするよう書き加える。 なお、「発行後に Zip アーカイブファイルの作成を行なう」フラグを表現する MSBuild プロパティの名前は何でもよく、スクリプトの実装者が決めればよい。 ここでは "MakeZipAfterPublish" というプロパティ名とすることとし、このプロパティに "true" と設定されていた場合にのみ Zip アーカイブファイルを作成する仕様としよう。 その場合、.csproj 内のターゲットの記述は下記要領となる。 ここまでの段階ではまだ、発行しても、MSBuild プロパティ ”MakeZipAfterPublish" の値は "true" ではない (既定だと空文字になる) ため、Zip アーカイブファイルは作成されない。 最後の仕上げとして、発行後に Zip アーカイブファイル作成を行ないたい各発行プロファイル (.pubxml) 中で、MSBuild プロパティ "MakeZipAfterPublish" の値に "true" を設定してやればよい。 こうすることで、Zip アーカイブファイル作成を行なう発行プロファイル (.pubxml) を使って発行を実行すると、プロジェクトファイルの内容 + その発行プロファイルの内容 が合成されて MSBuild が実行されるので、結果、以下の流れで Zip アーカイブファイルが生成されることとなる。
他の実現方法としては、Zip アーカイブファイル作成を行なうターゲット定義を、独立した外部の MSBuild スクリプトファイル (拡張子に決まりはないっぽいが .targets ファイルとか?) に書いておいて、発行プロファイル (.pubxml) からインポートするといった方法も思い浮かぶ。 補足本投稿では割愛するが、今回紹介したのと同じような要領で、「発行」時ではなく、「ビルド」時に、ビルド成果物のファイル群を自動で Zip アーカイブファイルにまとめるよう、MSBuild スクリプト (.csproj) を記述することも可能だ。 なお、ちょっとした注意事項だが、この MSBuild 標準の "ZipDirectory" タスク、拡張子やファイル名パターンを指定しての、Zip アーカイブファイルへの収録を除外することはできないようだ。 指定したフォルダの中身を、一切合切、Zip アーカイブファイルに収録してしまう他ないらしい。 拡張子やファイル名パターンを指定しての Zip アーカイブファイルへの収録を除外するには、MSBuild 標準の "ZipDirectory" タスクに頼らずに、MSBuild.Extension.Pack NuGet パッケージをプロジェクトに追加して、"MSBuild.ExtensionPack.Compression.Zip" タスクを利用するのがよさそうだ。 まとめ以上、Visual Studio や dotnet CLI を使っての、ASP.NET Core Web アプリケーション開発における、ファイルへの「発行」時に、自動で、発行成果物ファイル群を単一の Zip アーカイブファイルにまとめる、MSBuild を使った方法の紹介であった。 さてさて、しかしながら昨今であれば、何らかの CI/CD のパイプラインで、このような Zip アーカイブファイルを作成するのかな、と想像する (自分はよく知らない)。 また、Docker イメージを構築して、コンテナ上で稼働させるようなケースでは、単一の Docker イメージとして持ち歩けるので、このような Zip アーカイブファイルにまとめるような需要はそもそも発生しないことだろう。 ということで、今となっては、このような方式で、発行成果物の Zip アーカイブファイルを作成するケースはあまりないかもしれない。 ...ところで、MSBuild の v.15.8 って、いつリリースされたんでしたっけ??
by developer-adjust
| 2019-12-28 19:16
| .NET
|
ファン申請 |
||