/// <summary> /// Initialize /// 初期化します。 /// </summary> public WatchController() { //this.hungCount = 0; this.ProcessStatus = WatchController.processWatch(); //this.timerCallback = new TimerCallback(this.detectHungUp); //this.timer = new Timer(this.timerCallback); }
/// <summary> /// トリックスターのクライアントを監視し、一定時間「応答なし」になった場合に /// 強制終了を行うか可否の選択と、終了の処理を行います。 /// </summary> public void watcher() { status proc = WatchController.processWatch(); if (proc != status.End) { this.gameStats = stats.Start; // 起動中 if (this.ProcessStatus != status.Running) { this.ProcessStatus = status.Running; //SimpleLogger.WriteLine("Trickster Client start..."); } /* * 1回目の応答なし判定 * メモ:1回で応答なしとみなさない理由は、マップ移動やキャラクターデータ * 読み込み時にも一時的に応答なし状態として検出されてしまうため。 */ if (proc == status.Stop) { // 応答なし検出時 SimpleLogger.WriteLine("detected hunged up trickster."); /* * 検出時動作のsleep衝突によるアプリケーション自体のハングアップ回避のため、 * 一時的にタイマーを無効化 */ //timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); if (this.processStatus == status.Stop) { return; } this.ProcessStatus = status.Stop; SimpleLogger.WriteLine("sleep " + msec + "msec."); System.Threading.Thread.Sleep(msec); // sleep SimpleLogger.WriteLine("got up."); this.ProcessStatus = status.Running; proc = WatchController.processWatch(); if (proc == status.Running) { this.ProcessStatus = status.Running; SimpleLogger.WriteLine("detected to revive."); // 応答回復の場合は修理再開 timer.Enabled = true; return; } /* * 検出閾値時間分sleepしても応答がない場合は * 正式に応答なしと判定する */ if (proc == status.Stop) { this.ProcessStatus = status.Stop; // 一時的にtimerを無効化 timer.Enabled = false; SimpleLogger.WriteLine("Trickster process is hunged up !!"); System.Windows.Forms.DialogResult MsgRes = System.Windows.Forms.MessageBox.Show("Trickster の応答なしを検出しました。" + Environment.NewLine + "ゲームを強制終了しますか?", "Trickster Tools", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Warning, System.Windows.Forms.MessageBoxDefaultButton.Button2); if (MsgRes == System.Windows.Forms.DialogResult.Yes) { SimpleLogger.WriteLine("Trickster ProcessID: " + WatchController.TrickProcess.Id); try { WatchController.TrickProcess.Kill(); SimpleLogger.WriteLine("ProcessID: " + WatchController.TrickProcess.Id + " is killed."); this.ProcessStatus = status.ForceKilled; } catch (System.InvalidOperationException ioe) { SimpleLogger.WriteLine(ioe.Message); SimpleLogger.WriteLine("failed to kill " + WatchController.TrickProcess.Id); System.Windows.Forms.MessageBox.Show("ゲームの終了処理に失敗しました。", "Trickster Tools", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } catch (System.SystemException se) { SimpleLogger.WriteLine(se.Message); SimpleLogger.WriteLine("failed to kill " + WatchController.TrickProcess.Id); System.Windows.Forms.MessageBox.Show(se.Message, "Exceptional error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); System.Windows.Forms.MessageBox.Show("ゲームの終了処理に失敗しました。", "Trickster Tools", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } } else { SimpleLogger.WriteLine("ignore hungup"); //this.hungCount = 0; this.ProcessStatus = status.Running; } timer.Enabled = true; } } } else { // 終了時 // 起動した形跡があったらタスクバーの表示を試みる if (this.gameStats == stats.Start && (this.ProcessStatus == status.Running || this.ProcessStatus == status.ForceKilled)) { SimpleLogger.WriteLine("try to recover taskbar."); ProgramController.showTaskBar(); } this.processStatus = status.End; this.gameStats = stats.Shutdown; } }