none
カスタム動作で表示するダイアログをモーダルにするには? RRS feed

  • 質問

  • こんにちわ

    VS2005でインストーラを開発しているのですが、カスタム動作で自作ダイアログを出す際にそのダイアログをモーダルにする方法がわからず、困っています。

    ダイアログ自身はマニュアルどおりですがInstallメソッドをオーバーライドして、以下のような感じで表示できます。

     public override void Install(System.Collections.IDictionary stateSaver)
            {
                base.Install(stateSaver);
                  MainForm f = new MainForm();
                f.ShowDialog();

       }

    ShowDialog()する際にインストーラが出しているダイアログのウィンドウハンドルを渡してやればよさそうなのですが、それをどうやってとってくればいいのかがわかりません。どなたか、ご教示願えますか?

    2007年2月19日 2:19

すべての返信

  • 残念ですが、カスタム動作でUIはサポートされていません。なので、事前にダイアログを出し、ユーザーへの問い合わせなどは行っておくなど、カスタム動作でダイアログを用意せずとも動かせるようなインストーラにする必要があります。

    VSセットアッププロジェクトでは要求されているダイアログは用意できないということであれば、WiX や InstallShield など、作成上の制約の少ないインストーラ作成ツールを利用することをお勧めします。

    いずれにしても、カスタム動作ではUIを出して何かをするというのはデバッグのときくらいだけと思っておいた方がよいと思います。

    2007年2月19日 8:46
  • とっちゃんさん、返信ありがとうございます。

    やっぱりそうなんですか…orz。

    VSセットアッププロジェクトは、思いの他いろいろ制限があって(というか、機能が少ない)、ちょっと凝ったことをやろうとすると行き詰ることが多いですね。

    お勧めのインストーラ作成ツールを検討してみることにします。ありがとうございました。

    2007年2月21日 7:43
  • 確かに VSセットアッププロジェクトは制約が多いというか、できるようにしている部分が少ないというのはありますね。

    比較的要望の多い機能のひとつでもあるカスタムインストールはできませんし、シリアル番号の入力はできるものの既定の検証方法以外の手段を組み込むこともできませんしね。
    #他にもできないことは多数ありますけどw

    とはいえ、WiXやInstallShieldなどを利用したからと言って実現できるという保証もありません。

    WindowsInstaller で用意されているコントロール類は、あまり多くはなく(Windows3.0時代のコントロールにいくつか追加された程度)、独自にコントロールを用意することもできなければ、コントロールのサブクラス化などもできません。

    そのため、やりたいことが本当に実現できるという保証はないということだけは注意してください。

    どのようなUIが作れるのかは、WindowsInstaller SDK(MSDNライブラリにあります)のドキュメントを参照してください。

    英語ではありますが、そこに書かれているコントロールしかありませんのでw
    外部UI(VSのインストーラがこれ)を使うという方法もありますけど、情報はほとんどありません

    2007年2月22日 12:19
  • WiXを見始めたのですが、今回はとりあえず時間がなかったので、以下の方法で逃げました(Windowタイトルを探す伝家の宝刀ですが…)

    同じお悩みをお持ちの方、どうぞ。

    (WindowWrapperは他所で探してきたコードです。)

    public partial class Installer1 : Installer
    {
     ...

        public override void Install(System.Collections.IDictionary stateSaver)
            {
                base.Install(stateSaver);
                Process instp = GetInstallerProcess();
                MainForm f = new MainForm(true);
      
              if (instp == null) {
                    f.ShowDialog();
                } else {
                    f.ShowDialog(new WindowWrapper(instp.MainWindowHandle));
                }
       }

          Process GetInstallerProcess()
         {
                Process[] localByName;
                localByName = Process.GetProcessesByName("setup");
                foreach (Process p in localByName) {
                    if (p.MainWindowTitle == "Windowのタイトル") {
                        return p;
                    }
                }
                localByName = Process.GetProcessesByName("msiexec");
                foreach (Process p in localByName) {
                    if (p.MainWindowTitle == "Windowのタイトル") {
                        return p;
                    }
                }
                return null;
            }
     }
     public class WindowWrapper : System.Windows.Forms.IWin32Window
      {
            public WindowWrapper(IntPtr handle)
            {
                _hwnd = handle;
            }

            public IntPtr Handle
            {
                get { return _hwnd; }
            }

            private IntPtr _hwnd;
        }
    }

    2007年3月2日 2:38
  • その昔、msiのダイアログにちょいと細工をするために、同じようなことをしたことがあります。

    MSI-ML のアーカイブの #64 からのツリーでコントロールにスタイルを後付けするためにオーナーウィンドウを検索しています。

    ウィンドウクラスを使って探しているので、仕様の変更がなければ、タイトルにかかわりなくひっぱりだすことができますし、動かし方にも依存しません。

    ソースは乗せてませんが(断片コードだけ)、多少は参考になると思います。

    当時は、InstallShield でやってたので、そのあたりが追加されていますけど、msi の標準UI形式なら作成ツールは不問の方法です。

     

    2007年3月2日 4:03