Program.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using System;
  2. using System.Diagnostics;
  3. using System.Threading;
  4. using ivf_tl_Control; // AppData, StartMain
  5. using IvfTl.Control.Services; // Log4netHelper(程序集 ivf_tl_Control_Services;切勿写 operate 端 ivf_tl_Services)
  6. namespace IvfTl.ControlHost
  7. {
  8. public static class Program
  9. {
  10. private static Mutex _singleton;
  11. private static ControlHttpServer _http;
  12. private static volatile bool _started;
  13. private static ManualResetEventSlim _exitEvent;
  14. [STAThread]
  15. public static int Main(string[] args)
  16. {
  17. // 1) 单实例:已有 control 在跑则立即退出(永远只有一个驱动机器)。
  18. bool isNew;
  19. _singleton = new Mutex(true, @"Global\ivf_tl_control_singleton", out isNew);
  20. if (!isNew)
  21. {
  22. Log4netHelper.WriteLog("ControlHost: 已有实例在运行,本进程退出");
  23. return 0;
  24. }
  25. try
  26. {
  27. var hostArgs = HostArgs.Parse(args);
  28. Log4netHelper.WriteLog($"ControlHost 启动 port={hostArgs.Port} account={hostArgs.Account}");
  29. // 2) 先起 HTTP(让 operate 能尽早探到"在启动中"),started=false。
  30. _http = new ControlHttpServer(
  31. hostArgs.Port,
  32. BuildStatus,
  33. msg => Log4netHelper.WriteLog(msg));
  34. _http.Start();
  35. // 3) 账号守卫(对齐 operate 空账号跳过逻辑)。
  36. if (!hostArgs.IsValid)
  37. {
  38. Log4netHelper.WriteLog("ControlHost: 账号/密码为空,不启动采集(仅 HTTP 存活)");
  39. }
  40. else
  41. {
  42. // 4) 复刻 operate MainWindow 启动序(顺序不可变)。
  43. if (!AppData.Instance.Login(hostArgs.Account, hostArgs.Password))
  44. {
  45. Log4netHelper.WriteLog("ControlHost: control 登录失败");
  46. }
  47. else
  48. {
  49. if (!string.IsNullOrEmpty(hostArgs.CacheDisk))
  50. {
  51. ivf_tl_UtilHelper.PathHelper.pan = hostArgs.CacheDisk;
  52. AppData.Instance.LogService.Pan = hostArgs.CacheDisk;
  53. }
  54. try
  55. {
  56. IvfTl.Hardware.Impl.HardwareAccessLayer.Instance.Log =
  57. msg => Log4netHelper.WriteLog(msg);
  58. var devices = IvfTl.Hardware.Impl.HardwareAccessLayer.Instance.ScanDevices();
  59. Log4netHelper.WriteLog($"ControlHost: HAL 发现 {devices.Count} 个舱");
  60. }
  61. catch (Exception hex)
  62. {
  63. Log4netHelper.WriteLog("ControlHost: HAL 发现异常(降级):" + hex.Message);
  64. }
  65. var startMain = new StartMain();
  66. string err = startMain.StartRun(); // 阻塞:InitTL→InitHouse→StartAsync
  67. if (!string.IsNullOrEmpty(err))
  68. Log4netHelper.WriteLog("ControlHost: control 启动失败:" + err);
  69. else
  70. {
  71. _started = true;
  72. Log4netHelper.WriteLog("ControlHost: control 启动成功,常驻运行");
  73. }
  74. }
  75. }
  76. // 5) 驻留:control 后台线程已起(LongRunning),主线程阻塞等退出信号。
  77. _exitEvent = new ManualResetEventSlim(false);
  78. _exitEvent.Wait();
  79. return 0;
  80. }
  81. catch (Exception ex)
  82. {
  83. Log4netHelper.WriteLog("ControlHost 致命异常", ex);
  84. return 1;
  85. }
  86. finally
  87. {
  88. try { _http?.Stop(); } catch { }
  89. try { _singleton?.ReleaseMutex(); } catch { }
  90. }
  91. }
  92. /// <summary>提供给 HTTP /status 的快照(阶段1:基础存活;阶段2 接 GetMonitorSnapshot 补全)。</summary>
  93. private static StatusDto BuildStatus()
  94. {
  95. string tlSn = "";
  96. try { tlSn = AppData.Instance.TLSetting?.tlSn ?? ""; } catch { }
  97. return new StatusDto
  98. {
  99. Ok = true,
  100. Pid = Process.GetCurrentProcess().Id,
  101. TlSn = tlSn,
  102. Started = _started
  103. };
  104. }
  105. }
  106. }