次のようなコードで、OnDetectPackageCompleteで実行/キャンセルの確認ダイアログを表示し、OnApplyCompleteで終了メッセージが表示される。
参照に System.WIndows.Forms を追加。 using System.Windows.Forms; private void OnDetectPackageComplete(object sender, DetectPackageCompleteEventArgs e) { if (e.PackageId == "MyAppSetup.msi") { if (e.State == PackageState.Absent) { Engine.Plan(LaunchAction.Install); } else if (e.State == PackageState.Present) { DialogResult res = MessageBox.Show("MyAppSetup", "アンインストールを実行しますか?", MessageBoxButtons.OKCancel); if (res == DialogResult.Cancel) { Engine.Quit(0); } else { Engine.Plan(LaunchAction.Uninstall); } } } } private void OnApplyComplete(object sender, ApplyCompleteEventArgs e) { if (IsUninstall) { MessageBox.Show(ClassLibrary1.Properties.Resources.UnistallDone); } Engine.Quit(0); }せっかくmsiを多国語化したのに、Bootstarpperが未対応になってしまった。しかし、BootstarpperはC#のクラスライブラリなので、プロジェクトのProperties に String の Resouces.resx を追加することで多国語対応できる。
msiと同様、ベースを英語とし日本語のResources.ja.resxを追加した場合は次のようにBundle.wxs の BootstrapperApplicationRef にresources.dllを追加する。
<BootstrapperApplicationRef Id='ManagedBootstrapperApplicationHost'>
<Payload SourceFile="..\ClassLibrary1\bin\Release\ClassLibrary1.dll" />
<Payload SourceFile="..\ClassLibrary1\bin\Release\ja\ClassLibrary1.resources.dll"
Name="ja\ClassLibrary1.resources.dll" />
<Payload SourceFile="BootstrapperCore.config" />
</BootstrapperApplicationRef>
Name属性で ja サブフォルダを追加している。Name属性は展開先のパスで、デフォルト値はファイル名であるため、これがないと同じフォルダにファイルがフラットに展開され、resources.dllがロードされずベース言語のみとなる。
ここまでで、Cultureに従ってパラメータを切り替えて多国語化した msi を起動するBootstrapper作るという目的は一応実現した。しかし、これだけのためならdotNetInstallerを使ったBootstrapperのほうが目的に適っている。BurnをするならUIをBootstrapperに移し、msiはサイレントで実行した方がよい。
上記の方法ではインストール実行中、常時ウインドウを表示しておくことはできない。Runは独立したスレッドで呼ばれ、Runからリターンするとスレッドも終了し、ここで表示したFormも消えるか、下手をするとゾンビで残る。また Engine.Quit(0) を呼ぶとプロセスが終了しUIも終了してしまうので、UIが終了してから Engine.Quit(0) を呼ぶ必要がある。
そのためにはUI用のイベントループを作ればよい。ここではFormアプリによる実装例を紹介しておく。
Run メソッドで Detect を呼んだあと、Application によるループを開始する。
このループ終了後、Engine.Quit(0) を呼ぶ。
BootstapperとFormで相互に互いのインスタンスの参照を持ち、適宜メソッド呼び出し、変数設定などを行う。
/クラスライブラリにForm1を追加
private Form1 form;
protected override void Run()
{
this.DetectPackageComplete += this.OnDetectPackageComplete;
this.PlanComplete += this.OnPlanComplete;
this.ApplyComplete += this.OnApplyComplete;
this.ExecuteProgress += this.OnExecuteProgress;
if (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName == "ja")
{
Engine.StringVariables["TRANSFORMS"] = ":ja-JP.mst";
}
else
{
Engine.StringVariables["TRANSFORMS"] = "";
}
Engine.Detect();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
form = new Form1();
form.Bootstrapper = this;
Application.Run(form);
//formがクローズされると Application.Run が終了し、ここにくる。
this.Engine.Quit(0);
}
また、ExecuteProgressイベントで進行状態が通知される。ここでFormに通知を転送することができ、また ExecuteProgressEventArgs にResult.Cancelをセットするとインストールを中断することができる。
private void OnExecuteProgress(object sender, ExecuteProgressEventArgs e)
{
if ( someEroorCoccured )
{
e.Result = Result.Cancel;
}
else
{
form.SetProgress(e.OverallPercentage.ToString());
}
}
関連ブログ
VisualStudio 2017 Community & WiX tools & WiX Edit によるWindowsアプリ インストーラ(msi)作成
WiX toolset msi ダイアログ多国語対応
dotNetInstallerによるシンプルBootstarpper作成
WiX toolsetのBootstarpperを試してみた(1)
WiX toolsetのBootstarpperを試してみた(2)Detect追加
WiX toolsetのBootstarpperを試してみた(3)msiexecパラメータ設定
0 件のコメント:
コメントを投稿