VisualStudioで開発をして、ClickOnceで配布しているプロジェクトがあるんですが、ClickOnceでは不具合が出た時に1つ前のバージョンの戻せるとはいえ、それでは足りない事もままあります。
GitHubでReleaseを切る時に毎回zipを貼り付けておけば、いざという時はそこから任意のバージョンを取得して使ってもらえるのですが、それが面倒くさい。
ということで、VisualStudioのビルドイベントを使ってビルド後に自動でReleaseフォルダをzipで固めてくれるようにしました。
参考にさせていただいたのは、こちらの2ページ。
http://kuttsun.blogspot.com/2017/11/visual-studio-zip.html
https://sakapon.wordpress.com/2015/10/14/dotnet-build-2/
1つ目は.pdbなど不要ファイルを削除している点、2つ目はzipファイル名にバージョン番号を含めている点がそれぞれイケてるので、そのハイブリッドを目指しました。
出来上がったPowerShellスクリプトはこんな感じ。
# source assembly file path
if (-not ($Args[0])) { return 100 }
Add-Type -AssemblyName System.IO.Compression.FileSystem
$outputPath = "C:\\OutputDir\\zip"
$assemblyName = [System.IO.Path]::GetFileNameWithoutExtension($Args[0])
$assembly = [System.Reflection.Assembly]::LoadFrom($Args[0])
$assemblyFileVersion = [System.Reflection.CustomAttributeExtensions]::GetCustomAttribute($assembly, [System.Reflection.AssemblyFileVersionAttribute])
if (-not ($assemblyFileVersion)) { return 200 }
$sourceDirPath = [System.IO.Path]::GetDirectoryName($Args[0])
$targetZipFileName = [string]::Format("{0}-{1}.zip", $assemblyName, $assemblyFileVersion.Version)
$targetZipFilePath = [System.IO.Path]::Combine($outputPath, $targetZipFileName)
Remove-Item -Recurse -path $sourceDirPath -include *.pdb
Remove-Item -Recurse -path $sourceDirPath -include *.xml
Remove-Item -Recurse -path $sourceDirPath -include *.config -Exclude NLog.config
[System.IO.File]::Delete($targetZipFilePath)
[System.IO.Compression.ZipFile]::CreateFromDirectory($sourceDirPath, $targetZipFilePath)
元記事ではビルドイベントで出力パスを指定していましたが、他の開発メンバーは違うパスを指定したいこともあろうかと思い、(リポジトリに含まれない)PowerShellスクリプト側で指定するようにしました。パス区切りは「\」と2回打ってエスケープするの大事。
これを各プロジェクトフォルダの上、私の場合、C:\Users(ユーザ名)\Sources\ReposにCreateZipForAssembly.ps1という名前で保存しました。他のリポジトリのディレクトリが並んでいるのと同階層です。
で、VisualStudioの各プロジェクトでProperty->ビルドイベントを開き、「ビルド後のイベントのコマンドライン」に下記のように書きます。
if $(ConfigurationName) == Release (
cd $(ProjectDir)
powershell -ExecutionPolicy Unrestricted ..\..\CreateZipForAssembly.ps1 $(TargetPath)
)
cdで移動する$(ProjectDir)は、Hogeというプロジェクトの場合、Hoge\Hogeと潜った場所を指しているようなので、....\と2階層上がるとスクリプトに辿り着けるわけです。もちろん任意の場所に置いて絶対パスで指定しても良いでしょう。
基本的にはこれでReleaseビルドの度にoutputDirにzipが作られるはずです。ClickOnceの発行でも作成されるようです。私はClickOnce用ファイルを一旦ローカルに発行してから非IISなサーバーにアップロードしているので、それ用のパスの側にzipも書き出して、FTPでアップロードする時に見落とさないようにしてみました。
PowerShellはあまり馴染みがないのですが、エラーが起きた時にVisualStudioのエラー一覧には何も出てこないのでデバッグが大変でした。なにかやり方があるのかも知れません。