インストーラのウィンドウのハンドルさえ取得できれば、NativeWindow クラスを使って親子関係を持たせることもできるのですが、生憎取得できないようです。Process.MainWindowHandle で取得できるかとも思いましたが 0 が返ってきました。
そこで、ちょっと知恵を絞り出してみました。
internal static class MyMessageBox
{
public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
{
using (Form dummy = MyMessageBox.ShowDummyForm(caption))
{
return MessageBox.Show(dummy, text, caption, buttons, icon, defaultButton);
}
}
private static Form ShowDummyForm(string caption)
{
Form dummy = new Form();
dummy.TopMost = true;
dummy.ShowInTaskbar = true;
dummy.Opacity = 0;
dummy.ControlBox = false;
dummy.Text = caption;
dummy.Show();
return dummy;
}
}
最前面に固定された透明のダミーウィンドウを表示し、それをメッセージボックスの親ウィンドウにしたわけです。
この方法だとメッセージボックスがタスクバーに表示されませんが、ControlBox プロパティと Text プロパティを変更することで、ダミーウィンドウがちょうど良い具合に代わりを果してくれます。
メッセージボックスが最前面に固定されてしまうという副作用はありますが、まぁ問題ないでしょう。
あと、インストーラのウィンドウとダミーウィンドウ及びメッセージボックスはあくまで無関係ですので、メッセージボックス表示中もインストールウィンドウの操作が従来通りできてしまうことには注意してください。
このアカウントはファイル・ディレクトリへのアクセス権などが制限されていて、ログファイルを出力することすらできません。
これを解決するには、対象のファイル・ディレクトリへ適切な権限を付加する必要があります。
インストーラで、この権限付加の処理を行いたい場合、インストーラのカスタム動作でこれを行います。
以下に例を示します。
//using System;
//using System.Configuration.Install;
//using System.IO;
//using System.Security.AccessControl;
[RunInstaller(true)]
public partial class CustomInstaller : Installer
{
public CustomInstaller()
{
InitializeComponent();
}
public override void Install(System.Collections.IDictionary stateSaver)
{
string assemblyPathName = this.Context.Parameters["assemblypath"];
int fileDivisionIndex = assemblyPathName.LastIndexOf('\\');
string installDirectoryPathName = assemblyPathName.Remove(fileDivisionIndex);
DirectoryInfo installDirectoryInfo = new DirectoryInfo(installDirectoryPathName);
// インストール先ディレクトリの ACL ( アクセス制御リスト ) を取得
DirectorySecurity installDirectoryACL = installDirectoryInfo.GetAccessControl();
// Network Service アカウントの書き込み権限を表すオブジェクトを生成
FileSystemAccessRule writingAuthorityOfWorkerProcess = new FileSystemAccessRule("NT AUTHORITY\\NETWORK SERVICE", FileSystemRights.Write, AccessControlType.Allow);
// ACL に、Network Service アカウントの書き込み権限を追加する
installDirectoryACL.AddAccessRule(writingAuthorityOfWorkerProcess);
// インストール先ディレクトリの ACL を設定
installDirectoryInfo.SetAccessControl(installDirectoryACL);
base.Install(stateSaver);
}
}
この例では、インストール先ディレクトリに対して、Network Serviceアカウントが書き込みを行うための権限を付加しています。
これにより、Web アプリがインストール先ディレクトリ内にログファイルを出力することが可能となります。
インストーラ、カスタム動作自体の説明はここでは省略します。これについては以下のチュートリアルを参考にしてください。
Windows インストーラでの配置に関するチュートリアル