none
プロセス間通信を使用して、Windowの生成を行う方法について RRS feed

  • 質問

  • こんにちは。損と申します。
    Windowsアプリケーションで、別プロセスから呼ばれたメソッドの中で
    Windowを表示させようとしています。
    プロセス間通信はWCFで、netNamedPipeBindingを使用しています。

    下記のコードを実行し、別プロセスからCreateWindow()メソッドを呼ぶと、
    "System.InvalidOperationException: 呼び出しスレッドは、多数の UI コンポーネントが必要としているため、STA である必要があります。"
    という例外が発生してしまいます。

    UIスレッドのDispatcherを取得して、Invokeしてやる必要があるのだと思い、
    CreateWindow() メソッドの中で Application.Current.Dispatcher を取得しようとしましたが、今度は
    "System.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません。"
    という例外が発生してしまいました。

    基本的な部分かもしれませんが、Windowを表示するにはどうしたらよいか、
    御教授頂けないでしょうか。

    ---<以下、テストコード>---

    using System;
    using System.Windows;
    using System.ServiceModel;

    namespace Test
    {
        [ServiceContract]
        public interface IWindowTest
        {
            [OperationContract]
            void CreateWindow();
        }

        public class WindowTest : IWindowTest
        {
            delegate void delegateTest();

            [STAThread]
            static void Main(string[] args)
            {
                try
                {
                    // ServiceHostのインスタンス化
                    ServiceHost serviceHost = new ServiceHost(typeof(WindowTest));

                    // ServiceHostをOpenし、メッセージのリスニングを開始
                    serviceHost.Open();

                    MessageBox.Show("サービス起動中...");

                    // ServiceHostをCloseし、サービスをシャットダウン
                    serviceHost.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }

            // 別プロセスからプロセス間通信で呼ばれる
            public void CreateWindow()
            {
                delegateTest dT = new delegateTest(delegateMethodTest);

                dT.Invoke();

                return;
            }

            // CreateWindowメソッドから呼ばれる
            private void delegateMethodTest()
            {
                try
                {
                    Window win = new Window();  // ←ここでエラーが発生する
                    win.ShowDialog();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }
    }

    2009年12月21日 6:50

回答

  • どこかのスレッドで Application を new して Run しておかないとそりゃ Application.Current は null でしょう。
    また Application.ShutdownMode も考えておかないといけませんね。
    あとは毎回 AppDomain を分けて個別の Application オブジェクトを用意するって方法もありますが。

    // なんで非同期でもないのに delegateMethodTest をわざわざデリゲート越しに呼んでるのかしら?
    • 回答としてマーク 2009年12月21日 7:36
    2009年12月21日 7:23

すべての返信

  • どこかのスレッドで Application を new して Run しておかないとそりゃ Application.Current は null でしょう。
    また Application.ShutdownMode も考えておかないといけませんね。
    あとは毎回 AppDomain を分けて個別の Application オブジェクトを用意するって方法もありますが。

    // なんで非同期でもないのに delegateMethodTest をわざわざデリゲート越しに呼んでるのかしら?
    • 回答としてマーク 2009年12月21日 7:36
    2009年12月21日 7:23
  • メインスレッドでApplication を new して Run したところ、無事 Dispatcher を取得することができました。
    誠に有難うございます。初歩的な質問ですみません;

    // 色々試しているうちに、Invokeにしてしまっていましたが、デリゲート越しに非同期で呼ぶ予定です;

    2009年12月21日 7:36