Ejemplo n.º 1
0
        /// <summary>
        /// 開始。
        /// </summary>
        /// <param name="terminalWindow">端末ウィンドウ。</param>
        public static void StartCore(IntPtr terminalWindow)
        {
            //コントロールスレッド終了管理スレッド
            //システムに負荷をかけない程度で端末プロセス、コントローススレッド、メインスレッドを監視する
            new Thread((ThreadStart) delegate
            {
                Debug.Trace("Start waiting thread.");

                //コントロールウィンドウのハンドル格納用
                object sync = new object();
                IntPtr controlWindowHandle = IntPtr.Zero;

                //コントロールスレッド起動
                //処理に対して素早く対応するためGetMessageを使用する
                Thread controlThread = new Thread((ThreadStart) delegate
                {
                    using (SystemControlWindowInApp window = new SystemControlWindowInApp())
                    {
                        NativeMethods.MSG msg = new NativeMethods.MSG();
                        lock (sync)
                        {
                            controlWindowHandle = window.Handle;
                        }
                        while (true)
                        {
                            if (NativeMethods.GetMessage(ref msg, window.Handle, 0, 0) == 0)
                            {
                                break;
                            }
                            NativeMethods.TranslateMessage(ref msg);
                            NativeMethods.DispatchMessage(ref msg);
                        }
                    }
                });
                controlThread.Start();

                //ウィンドウハンドル生成待ち
                while (true)
                {
                    lock (sync)
                    {
                        if (controlWindowHandle != IntPtr.Zero)
                        {
                            break;
                        }
                    }
                    Thread.Sleep(10);
                }

                Debug.Trace("Control Window Created.");

                //対象プロセスのIDを取得
                int windowProcessId = 0;
                NativeMethods.GetWindowThreadProcessId(terminalWindow, out windowProcessId);

                //端末側にコントロールウィンドウのハンドルを送信する
                NativeMethods.SendMessage(terminalWindow, WM_NOTIFY_SYSTEM_CONTROL_WINDOW_HANDLE, controlWindowHandle, IntPtr.Zero);

                //終了待ち
                EventHandler appExit         = new EventHandler(delegate { NativeMethods.PostMessage(controlWindowHandle, NativeMethods.WM_QUIT, IntPtr.Zero, IntPtr.Zero); });
                Application.ApplicationExit += appExit;
                Debug.Trace("Success in App.");
                using (Process windowProcess = GetProcessById(windowProcessId))
                    while (windowProcess != null)
                    {
                        //通信プロセスが消えたら終わり
                        windowProcess.Refresh();
                        if (windowProcess.HasExited)
                        {
                            break;
                        }

                        //コントロールスレッドが終了したら終わり
                        if (!controlThread.IsAlive)
                        {
                            break;
                        }

                        Thread.Sleep(200);
                    }

                //コントロールスレッド終了
                while (controlThread.IsAlive)
                {
                    NativeMethods.PostMessage(controlWindowHandle, NativeMethods.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
                    Thread.Sleep(10);
                }

                Application.ApplicationExit -= appExit;

                //メモリ解放
                GC.Collect();
            }).Start();
        }
        /// <summary>
        /// 開始。
        /// </summary>
        /// <param name="targetProcessId">対象プロセスID。</param>
        /// <returns>レスポンス受信用ウィンドウハンドル。</returns>
        internal IntPtr Start(int targetProcessId)
        {
            IntPtr recieveWindowHandle = IntPtr.Zero;
            object sync = new object();

            _recieveThread = new Thread((ThreadStart) delegate
            {
                using (RecieveWindow window = new RecieveWindow())
                {
                    lock (sync)
                    {
                        recieveWindowHandle = window.Handle;
                    }

                    //受信待ち
                    while (!window.IsError)
                    {
                        NativeMethods.MSG msg = new NativeMethods.MSG();
                        if (NativeMethods.PeekMessage(ref msg, window.Handle, 0, 0, NativeMethods.PeekMsgOption.PM_REMOVE))
                        {
                            NativeMethods.TranslateMessage(ref msg);
                            NativeMethods.DispatchMessage(ref msg);
                        }
                        if (window.SystemControlWindowHandle != IntPtr.Zero)
                        {
                            lock (sync)
                            {
                                _systemControlWindowInAppHandle = window.SystemControlWindowHandle;
                            }
                            break;
                        }
                        Thread.Sleep(10);

                        //通信プロセスが消えたら終わり
                        try
                        {
                            if (Process.GetProcessById(targetProcessId) == null)
                            {
                                break;
                            }
                        }
                        catch
                        {
                            break;
                        }
                    }
                    lock (sync)
                    {
                        _errNo = window.ErrNo;
                    }
                }
            });
            _recieveThread.Start();

            //受信ウィンドウ生成待ち。
            while (true)
            {
                lock (sync)
                {
                    if (recieveWindowHandle != IntPtr.Zero)
                    {
                        break;
                    }
                }
            }
            return(recieveWindowHandle);
        }