using Google.Protobuf.WellKnownTypes; using ivf_tl_Com; using IvfTl.Control.Entity.DTO; using IvfTl.Control.Entity.DTO.ApiRequestDTO; using IvfTl.Control.Entity.DTO.ControllerResults; using IvfTl.Control.Entity.GlobalEntitys; using IvfTl.Control.Entity.GlobalEnums; using IvfTl.Control.Entity.InitEntitys; using ivf_tl_UtilHelper; using Newtonsoft.Json; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; using System.Windows; namespace ivf_tl_Control { public class StartMain { AppData AppData { get; set; } public int CamNum { get; set; } = 0; public StartMain() { //HouseBin houseBin = new HouseBin(); //houseBin.ComBin._channel.ErrorLogEvent += AppData.logControl.TLLog; //houseBin.ComBin._channel.ExceptionLogEvent += AppData.logControl.ExceptionLog; //houseBin.ComBin._channel.CommandLogEvent += AppData.logControl.HouseLog; } public string StartRun() { try { string errorInfo = ""; AppData = AppData.Instance; AppData.LogService.TLLog($"程序开始启动", LogEnum.RunRecord); var initTLResult = InitTL(ref errorInfo); if (!string.IsNullOrEmpty(errorInfo)) return errorInfo; if (errorInfo == "结束") return errorInfo; AppData.TLSetting = initTLResult.Item1.TLSetting; PathHelper.pan = initTLResult.Item1.TLSetting.tmpDir; AppData.LogService.Pan = initTLResult.Item1.TLSetting.tmpDir; if (!InitHouse(initTLResult.Item1, initTLResult.Item2, ref errorInfo)) return errorInfo; AppData.StartAsync().Wait(); return null; } catch (Exception ex) { AppData.LogService.ExceptionLog(ex, "仪器初始化", null, LogEnum.RunException); return ex.Message; } } /// /// TL数据初始化 /// /// public (TLInitControllerResult, List) InitTL(ref string errora) { try { SerialBin serialBin = new SerialBin(); serialBin.TLLogEvent += AppData.LogService.TLLog; serialBin.ExceptionLogEvent += AppData.LogService.ExceptionLog; serialBin.HouseLogEvent += AppData.LogService.HouseLog; var errorList = serialBin.UpdataCamera(); AppData.LogService.TLLog($"相机信息:{JsonConvert.SerializeObject(serialBin.CCDidSn)}", LogEnum.RunRecord); if (errorList.Any()) { // 舱室故障隔离:相机枚举异常不再整机中止,只记日志;受影响舱稍后在 CCDSN 配对时落坏舱被剔除。 AppData.LogService.TLLog($"相机枚举有异常(不中止,受影响舱将按坏舱剔除):{JsonConvert.SerializeObject(errorList)}", LogEnum.RunRecord); } CamNum = serialBin.CCDidSn.Where(x => x.Value != null).Count(); errorList = serialBin.Start(); AppData.LogService.TLLog($"仓室信息:{JsonConvert.SerializeObject(serialBin.SerialModels)}", LogEnum.RunRecord); AppData.LogService.TLLog($"E方数据:{JsonConvert.SerializeObject(serialBin.HouseEEPROInfos)}", LogEnum.RunRecord); if (errorList.Any()) { // 舱室故障隔离:扫口异常不再整机中止,剔除坏舱后用好舱继续(见下方 RunnableHouses)。 AppData.LogService.TLLog($"扫口有异常(将剔除坏舱后继续):{JsonConvert.SerializeObject(errorList)}", LogEnum.RunRecord); } var modelCount = serialBin.SerialModels.Count; if (modelCount != 11) { // M1-01 步骤2:合并后是单进程无人值守前台,不能弹模态框。 // 原 hack(MessageBox + Task.Delay(3000) + FindWindow/EnumChildWindows/SendMessage(BM_CLICK) 自动点 Yes) // 改为静默 + 日志记录;是否继续由配置项 ContinueOnModuleCountMismatch 控制(默认继续)。 // 相关 [DllImport] 声明(FindWindow/SendMessage/EnumChildWindows/GetClassName/GetWindowText)按代码隔离原则保留为死代码,仅停止调用。 bool continueOnMismatch = true; try { string cfg = System.Configuration.ConfigurationManager.AppSettings["ContinueOnModuleCountMismatch"]; if (!string.IsNullOrEmpty(cfg) && bool.TryParse(cfg, out bool parsed)) continueOnMismatch = parsed; } catch { /* 读取配置失败时按默认(继续)处理 */ } AppData.LogService.TLLog($"检测到 {modelCount} 个模块(期望 11),ContinueOnModuleCountMismatch={continueOnMismatch},按配置策略{(continueOnMismatch ? "继续运行" : "中止初始化")}", LogEnum.RunRecord); if (!continueOnMismatch) { errora = "结束"; return (new TLInitControllerResult(), new List()); } } // 舱室故障隔离:坏舱 = 故障清单中已知舱号;可跑舱 = 发现的舱 − 坏舱;仅零可跑才整机中止。 var discovered = serialBin.SerialModels.Select(x => x.houseSn).ToList(); List listIntRunHoues = StartupFaultPolicy.RunnableHouses(discovered, serialBin.Faults); foreach (var f in serialBin.Faults) if (f.HouseSn > 0) f.Isolated = true; AppData.StartupFaults = serialBin.Faults; if (serialBin.Faults.Any()) AppData.LogService.TLLog($"启动坏舱清单:{JsonConvert.SerializeObject(serialBin.Faults)};可跑舱:{string.Join(",", listIntRunHoues)}", LogEnum.RunRecord); if (StartupFaultPolicy.IsFatal(listIntRunHoues)) { errora = "所有舱室初始化失败,无可运行舱室"; AppData.LogService.TLLog(errora, LogEnum.RunRecord); return (new TLInitControllerResult(), new List()); } // 启动期坏舱经现有 reportAlarm 报警闭环上报(alarm 表/双端列表/短信电话/可消警);失败不影响启动。 try { AppData.ReportStartupFaults(); } catch { } TLInitData tLInitData = new TLInitData(); tLInitData.tlSn = $"NEO-1-{serialBin.TLNum}"; tLInitData.dayLighting = serialBin.dayLighting; tLInitData.softwareVersion = "V2.0.0"; tLInitData.verticalMotorPulseMax = 125000; tLInitData.houseLinkDataList = serialBin.SerialModels.OrderBy(x => x.houseSn).ToList(); foreach (var item in serialBin.HouseEEPROInfos) { item.tlSn = tLInitData.tlSn; } tLInitData.houseEEPROInitDTOList = serialBin.HouseEEPROInfos.OrderBy(x => x.houseSn).ToList(); AppData.LogService.TLLog($"【CamNum:{CamNum}】设备基础数据:{JsonConvert.SerializeObject(tLInitData)}", LogEnum.RunRecord); TLInitControllerResult tLInitControllerResult = AppData.SerialBinController.UpdateTLInfoController(tLInitData); if (tLInitControllerResult == null) { errora = "获取TL设置失败"; AppData.LogService.TLLog(errora, LogEnum.RunRecord); return (new TLInitControllerResult(), new List()); } //AppData.LogService.TLLog($"TL初始化结果:{JsonConvert.SerializeObject(tLInitControllerResult)};{string.Join("_", listIntRunHoues)}", LogEnum.RunRecord); return (tLInitControllerResult, listIntRunHoues); } catch (Exception ex) { errora = ex.Message; AppData.LogService.ExceptionLog(ex, "数据初始化", null, LogEnum.RunException); return (new TLInitControllerResult(), new List()); } } /// /// 仓室初始化 /// /// /// /// /// private bool InitHouse(TLInitControllerResult tLInitControllerResult, List runHouses, ref string errorInfo) { try { TLSetting tLSetting = tLInitControllerResult.TLSetting; AppData.TLSetting = tLSetting; var allList = AppData.SerialBinController.GetDishAndBalanceDataController(tLSetting.tlSn); int housesn = 11; AppData.BufferBottleBin = new BufferBottleBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), AppData.Instance.guanbiTime); AppData.InitBufferBottleBinEvent(AppData.BufferBottleBin); housesn = 1; AppData.HouseBin1 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin1); housesn = 2; AppData.HouseBin2 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin2); housesn = 3; AppData.HouseBin3 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin3); housesn = 4; AppData.HouseBin4 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin4); housesn = 5; AppData.HouseBin5 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin5); housesn = 6; AppData.HouseBin6 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin6); housesn = 7; AppData.HouseBin7 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin7); housesn = 8; AppData.HouseBin8 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin8); housesn = 9; AppData.HouseBin9 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin9); housesn = 10; AppData.HouseBin10 = new HouseBin(tLSetting, tLInitControllerResult.HouseList.FirstOrDefault(x => x.houseSn == housesn), allList.Dishes.FirstOrDefault(x => x.houseSn == housesn), allList.BalanceList.FirstOrDefault(x => x.houseSn == housesn), tLInitControllerResult.HouseWellList.Where(x => x.houseSn == housesn).ToList()); AppData.InitHouseBinEvent(AppData.HouseBin10); AppData.HouseBin1.CamNum = CamNum; AppData.HouseBin2.CamNum = CamNum; AppData.HouseBin3.CamNum = CamNum; AppData.HouseBin4.CamNum = CamNum; AppData.HouseBin5.CamNum = CamNum; AppData.HouseBin6.CamNum = CamNum; AppData.HouseBin7.CamNum = CamNum; AppData.HouseBin8.CamNum = CamNum; AppData.HouseBin9.CamNum = CamNum; AppData.HouseBin10.CamNum = CamNum; if (!AppData.MvcTest) { if (runHouses.Contains(1)) AppData.HouseBin1.StartTask(); if (runHouses.Contains(2)) AppData.HouseBin2.StartTask(); if (runHouses.Contains(3)) AppData.HouseBin3.StartTask(); if (runHouses.Contains(4)) AppData.HouseBin4.StartTask(); if (runHouses.Contains(6)) AppData.HouseBin6.StartTask(); if (runHouses.Contains(7)) AppData.HouseBin7.StartTask(); if (runHouses.Contains(8)) AppData.HouseBin8.StartTask(); if (runHouses.Contains(9)) AppData.HouseBin9.StartTask(); if (runHouses.Contains(10)) AppData.HouseBin10.StartTask(); } if (runHouses.Contains(5)) AppData.HouseBin5.StartTask(); if (runHouses.Contains(11)) AppData.BufferBottleBin.StartTask(); return true; } catch (Exception ex) { AppData.LogService.ExceptionLog(ex, "仓室初始化", null, LogEnum.RunException); errorInfo = ex.Message; return false; } } public void testc() { AppData = AppData.Instance; string body1 = AppData.ReadText(@"C:\Users\jxb\Desktop\work\10 时差\8 开发文档\6 服务器架构\link接口请求参数.txt"); string body2 = AppData.ReadText(@"C:\Users\jxb\Desktop\work\10 时差\8 开发文档\6 服务器架构\init接口请求参数.txt"); //AppData.SerialBinController.TLInitController(body1, body2); } public void testGetAutoFocusController() { AppData = AppData.Instance; PositionRequestDTO autoFocusDTO = new PositionRequestDTO { tlSn = "NEO-1-20230101", houseSn = 1, }; AppData.HouseBinController.GetAutoFocusController(autoFocusDTO); } public void TestGetCCDPositionController() { AppData = AppData.Instance; PositionRequestDTO autoFocusDTO = new PositionRequestDTO { tlSn = "NEO-1-20230101", houseSn = 1, }; AppData.HouseBinController.GetCCDPositionController(autoFocusDTO); } public void TestGetDishAndBalanceDataController() { AppData = AppData.Instance; //AppData.HouseBinController.GetDishAndBalanceDataController("NEO-1-20230101"); } [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll")] static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); const uint WM_CLOSE = 0x0010; const uint BM_CLICK = 0x00F5; } }