/// <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); }