概要
Windowsのインストーラ作成にVisual Studioの拡張機能Microsoft Visual Studio Installer Projects(以降、Installer Projectsと呼ぶ)を使用している方も多いだろう。
インストール後にInstaller Projectsの標準機能では実行できない複雑な処理をする場合はカスタム動作を別途定義してイベント発生時に呼び出す場合がある。
カスタム動作について調べている中でいくつかクセを発見したのでメモしておく。
テスト用セットアッププロジェクト
Installer Projectsのセットアッププロジェクト(TestSetup
)からカスタム動作用DLL(CustomAction1
、CustomAction2
)を呼び出している。
カスタム動作の基本的な説明はこの神記事を見ればたちどころにわかる。
カスタム動作の実行順序はこの神記事が非常に詳しい。
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections;
namespace CustomAction1
{
[RunInstaller(true)]
public class CustomAction1 : System.Configuration.Install.Installer
{
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
MessageBox.Show(GetType().Name + ": Install");
}
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
MessageBox.Show(GetType().Name + ": Commit");
}
public override void Rollback(IDictionary savedState)
{
base.Rollback(savedState);
MessageBox.Show(GetType().Name + ": Rollback");
}
public override void Uninstall(IDictionary savedState)
{
base.Uninstall(savedState);
MessageBox.Show(GetType().Name + ": Uninstall");
}
}
}
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections;
namespace CustomAction2
{
[RunInstaller(true)]
public class CustomAction2 : System.Configuration.Install.Installer
{
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
MessageBox.Show(GetType().Name + ": Install");
}
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
MessageBox.Show(GetType().Name + ": Commit");
}
public override void Rollback(IDictionary savedState)
{
base.Rollback(savedState);
MessageBox.Show(GetType().Name + ": Rollback");
}
public override void Uninstall(IDictionary savedState)
{
base.Uninstall(savedState);
MessageBox.Show(GetType().Name + ": Uninstall");
}
}
}
RemovePreviousVersions=TrueのときはUninstallのカスタム動作が呼ばれない?
セットアッププロジェクトのRemovePreviousVersions
をTrue
にすると新しいバージョンのソフトをインストールする際(バージョンアップ時)に古いバージョンのソフトを自動的にアンインストールしてくれる。
これをしないと複数の異なるバージョンが1つのPC内に同居する状態になってしまう場合があり、不都合が生じる可能性がある。
ここで注意すべきなのは古いバージョンのアンインストール時にカスタム動作のUninstall
は実行されないことである。
RemovePreviousVersions=True
でバージョンアップするなら、古いバージョンを削除したときにして、
Uninstall
のカスタム動作が呼ばれるかも?と思ったが、
実際は新しいバージョンのInstall
、Commit
のカスタム動作が実行されるだけである。
まあ現状の仕様のほうが多くの人にメリットがあるように思う。
インストール開始前に実行できるカスタム動作はない?
実はカスタム動作として使用できるのはInstall
、Commit
、Rollback
、Uninstall
だけではなく、この記事で紹介されているOnBeforeInstall
やOnAfterInstall
などもある。
その中でもOnBeforeInstall
はインストール先の環境のチェックやインストール可否の制御に使用できそうな気がするが、
OnBeforeInstall
の実行タイミングはファイルの配置がすべて完了した後であって、インストールのプロセスがかなり進んだ後なのだ。
さらに困ったことにインストールを否認した場合のエラーメッセージが非常に不親切なのである。
たとえばCustomAction1.cs
に以下のコードを追加して人為的に例外を返してやる。
これによってインストールが途中で中断されるはずだ。
protected override void OnBeforeInstall(IDictionary savedState)
{
base.OnBeforeInstall(savedState);
MessageBox.Show(GetType().Name + ": OnBefore");
throw new System.Configuration.Install.InstallException("Errorだあああああ");
}
ここでOnBeforeInstall
が実行されて例外発生を示すメッセージが表示されるが、なんだか不親切な嫌な感じ。
最後はこれ。今回カスタム動作用のDLLを2つ使っているため表示されるものと思われる。
もっとこう…あるだろう!!という感じだ。
インストーラの「起動条件」でもインストーラ実行可否の制御はできると思うが、凝ったことをやるのには不向きである。
いいやり方があれば誰か教えてください。