using System; using System.Diagnostics; using System.Threading; using ivf_tl_Control; // AppData, StartMain using IvfTl.Control.Services; // Log4netHelper(程序集 ivf_tl_Control_Services;切勿写 operate 端 ivf_tl_Services) namespace IvfTl.ControlHost { public static class Program { private static Mutex _singleton; private static ControlHttpServer _http; private static volatile bool _started; private static ManualResetEventSlim _exitEvent; [STAThread] public static int Main(string[] args) { // 1) 单实例:已有 control 在跑则立即退出(永远只有一个驱动机器)。 bool isNew; _singleton = new Mutex(true, @"Global\ivf_tl_control_singleton", out isNew); if (!isNew) { Log4netHelper.WriteLog("ControlHost: 已有实例在运行,本进程退出"); return 0; } try { var hostArgs = HostArgs.Parse(args); Log4netHelper.WriteLog($"ControlHost 启动 port={hostArgs.Port} account={hostArgs.Account}"); // 2) 先起 HTTP(让 operate 能尽早探到"在启动中"),started=false。 _http = new ControlHttpServer( hostArgs.Port, BuildStatus, msg => Log4netHelper.WriteLog(msg)); _http.Start(); // 3) 账号守卫(对齐 operate 空账号跳过逻辑)。 if (!hostArgs.IsValid) { Log4netHelper.WriteLog("ControlHost: 账号/密码为空,不启动采集(仅 HTTP 存活)"); } else { // 4) 复刻 operate MainWindow 启动序(顺序不可变)。 if (!AppData.Instance.Login(hostArgs.Account, hostArgs.Password)) { Log4netHelper.WriteLog("ControlHost: control 登录失败"); } else { if (!string.IsNullOrEmpty(hostArgs.CacheDisk)) { ivf_tl_UtilHelper.PathHelper.pan = hostArgs.CacheDisk; AppData.Instance.LogService.Pan = hostArgs.CacheDisk; } try { IvfTl.Hardware.Impl.HardwareAccessLayer.Instance.Log = msg => Log4netHelper.WriteLog(msg); var devices = IvfTl.Hardware.Impl.HardwareAccessLayer.Instance.ScanDevices(); Log4netHelper.WriteLog($"ControlHost: HAL 发现 {devices.Count} 个舱"); } catch (Exception hex) { Log4netHelper.WriteLog("ControlHost: HAL 发现异常(降级):" + hex.Message); } var startMain = new StartMain(); string err = startMain.StartRun(); // 阻塞:InitTL→InitHouse→StartAsync if (!string.IsNullOrEmpty(err)) Log4netHelper.WriteLog("ControlHost: control 启动失败:" + err); else { _started = true; Log4netHelper.WriteLog("ControlHost: control 启动成功,常驻运行"); } } } // 5) 驻留:control 后台线程已起(LongRunning),主线程阻塞等退出信号。 _exitEvent = new ManualResetEventSlim(false); _exitEvent.Wait(); return 0; } catch (Exception ex) { Log4netHelper.WriteLog("ControlHost 致命异常", ex); return 1; } finally { try { _http?.Stop(); } catch { } try { _singleton?.ReleaseMutex(); } catch { } } } /// 提供给 HTTP /status 的快照(阶段1:基础存活;阶段2 接 GetMonitorSnapshot 补全)。 private static StatusDto BuildStatus() { string tlSn = ""; try { tlSn = AppData.Instance.TLSetting?.tlSn ?? ""; } catch { } return new StatusDto { Ok = true, Pid = Process.GetCurrentProcess().Id, TlSn = tlSn, Started = _started }; } } }