2026-06-22 全量源码梳理(3 路并行核实),一切以源码为准,关键处标
file:line。 用途:接手 operate(操作端 WPF)这套合并后代码的全图;与control-逻辑与配置全景.md互为两半(control=机器驱动大脑,operate=人机交互+承载 control)。 行号若无另注,均指ivf_tl_operate_2.0/ivf_tl_Operate/(现有合并版)下对应文件;差异对照基准版临时文件/ivf_tl_operate_2.0/ivf_tl_Operate/。 ⚠ 第八节是本文核心:合并后相对基准的改动/降级/待验证项登记(operate 侧)——control 全景管不到这半边,坑都在这里。
operate = 培养箱的"人机交互端 + control 宿主":登录→显示舱室/胚胎/曲线/报警→工程师调试(借 control 串口动硬件)→改配置/加皿/管胚胎,全走 HTTP 与服务器交互;合并后还在自己进程里把 control 当类库托起来跑(Task.Run StartRun),所以现在"一个软件"= operate UI 进程内含 control 驱动线程。
关键现状(合并引入):
ivf_tl_Control.AppData.Login → HAL.ScanDevices → StartMain.StartRun()(MainWindow.xaml.cs:67-132)。这是"operate 关了 control 也跟着死"的根源,也是双进程拆分要拆的点。new ComBin/new Camera 直开物理口",改为向 HAL 借用采集端同一物理句柄(gate.Acquire(OperateDebug)),用完只归还不关口。control/IvfTl.Hardware/Impl/SerialChannelImpl.cs(control 端缺 Commander builder)。单实例(Mutex ivf_tl_Operate)。启动顺序:
| 序 | 触发点 | file:line | 做了什么 |
|---|---|---|---|
| ① | App() 构造 |
App.xaml.cs:25-31 | 记日志;注册 App_Startup/App_Exit(App_Exit 体为空——退出语义缺失) |
| ② | OnStartup |
App.xaml.cs:33-46 | 单实例互斥,已运行则提示并 Shutdown;开 Stylus 触控 |
| ③ | App_Startup |
App.xaml.cs:52-68 | 注册 UI/Task/非UI 三类全局异常;MigratePlaintextCredentials()(明文口令一次性加密回写,须先于读凭据);InitOperationLog();ClickTrailLogger.Install()(全局点击层);ChangeLanguage() |
| ④ | InitOperationLog |
App.xaml.cs:74-96 | 起操作日志:project=operate、Kafka=kfkaIP:kfkaPort(缺则 127.0.0.1:9092)、topic=tl-oplog、配置 exe 同目录 oplog-config.json;全 try 兜底 |
| ⑤ | MainWindow() 构造 |
MainWindow.xaml.cs:27-45 | 把 MainGrid 包进 Viewbox(Uniform)做竖屏自适应(合并去掉了 #if DEBUG,Release 也生效) |
| ⑥ | MainWindow_Loaded |
MainWindow.xaml.cs:47-61 | 弹 LoginWindow.ShowDialog(),失败则关窗退出;成功后建 MainPageViewModel(TlSn)+首页 |
| ⑦ | 登录提交 | LoginWindow.xaml.cs:42-95 | 校验账号/密码/设备号;AppData.AppDataInit() 成功后 setAppConfig() 写回 |
| ⑧ | AppDataInit |
AppData.cs:114-147 | 建 HttpHelper→云端校验账号→置 TlNum/TlSn(NEO-1-{TlNum})→建 MqttHelper(连 broker 订阅)→拉 TLSettingCommon+受精类型字典→设操作日志上下文 |
| ⑨ | 登录后后台线程 | MainWindow.xaml.cs:67-132 | Task.Run 托管 control:ivf_tl_Control.AppData.Login(同账号透传)→ LogService.Pan=cacheDisk → HAL.ScanDevices()(设备发现一次)→ StartMain.StartRun()(阻塞常驻)。全程异常只记日志、不退进程(已去掉 control 原 Environment.Exit) |
control 登录窗(Window1)已从启动路径剔除,改由 operate 单登录账号透传。
ScanDevices仅在 ⑨ 调一次,保证前后台拿同一组句柄。
Windows/(独立窗口):LoginWindow(登录,内置软键盘)、MessageWindow/MessagePrompt(提示/确认)、GetDateWindow(选日期)、PhotoWindowNew(看图)。
View/(MainWindow 容器内切换的 UserControl):MainPageView(首页舱室总览)、DetailPageView(胚胎详情,含 10s 报警轮询)、PhotoPageView/ChartPageView/AlarmPageView/DishRecordView、HouseSettingPageView/HouseDebugPageView/AutoFocusSettingView/CCDSettingView/BufferDebugView、SettingPageView/AboutView/AddDishWindowView、ServiceMonitorView(新增)、UnifiedConfigView(新增)。
CustomUserControls/:CustomHouseInfo/CustomDishInfo/PhotoBox/AlarmControl 等;SoftKeyboard+SoftKeyboardHost(新增,替代 osk.exe)。
导航:单容器 MainWindow._container.Content,LoadPage(UserControl)(MainWindow.xaml.cs:135)切页,AppData.BackMainPage()(AppData.cs:177)回首页。无导航框架。
凡"动硬件"均走
Serial.*/Cam.*(= HAL 借用句柄 → control 串口/相机);凡"查/改数据"均走AppData.Instance.HttpHelper.*(HTTP)。
MainPageViewModel(1023 行)Init():142→GetHouseCultureListApi;报警轮询 StartThread():745→SearchAlarmHistoryNumApi/TlInfoTimeApi/SearchAlarmHistoryApi;报警静音 SetAlarmMute:957;MQTT 实时 RecMqttMessage():516。EndDish(houseSn):347 —— 仅本地清空 ExDish/发育时间,无 HTTP 下发(注意:与"皿管理结束培养走 HTTP"是两条路)。ivf_tl_Control.AppData.Instance.LastHttpOkAt = DateTime.Now(HTTP 成功时反写 control 单例,供监控透出)。HouseDebugPageViewModel(1592 行,基准 954)ComHouseInit():244 —— HAL.GetHouseGate(houseSn).Acquire(OperateDebug):256-257 借用;返回 null=该舱正被采集占用→提示重试(:258-262),异常→提示并退出(:264-268)。Serial/Cam = _halLease.Serial/.Camera(:44/46)。ComHouseUnit():355 —— 只 Dispose() 归还,绝不 ClosePort/UnInit(:359-360,否则关掉采集端口)。RedTem:383、压 RedPre:392、门 RedDoor:401。HouseVent:510。WriteOpenIntakeTime:520(真下发)、垂直间隔脉冲 WriteOVerSpace:565、保存水平位 SaveWellHor:579。SavePic:748、水平抓图 ShuiPingZhuaPai:775、清晰图层抓图 AutoFocusPic:834。Serial/Cam 喂 new CalibrationEngine(...)(见 DebugCalibrationAdapter.cs)。AutoFocusSettingViewModel(33 行,两版相同)FocusSettingApi(TlSn):19。无串口/降级。DebugCalibrationAdapter.LayerPreviewItem(PhotoLayerCalculator.ComputeLayerPositions)。BufferDebugViewModel(311 行,基准 273)ComHouseInit():154 借用缓冲瓶舱(houseSn=11),ComHouseUnit():208 归还。BufferState():229;补气 Are():238;进气阀时间 writeE:251→WriteOpenIntakeTimeWait(...,isBuffer:true):259(真下发)+HTTP LightsUpdateApi:261;读灯光 RedL():285(真读)。View/AddDishWindowView.xaml.cs):AddCultureRecordApi:614、UpdateDishInfoApi:426、StartBalanceApi:669/StopBalanceApi:655。纯 HTTP,无降级。DetailPageViewModel(101 行,两版相同):Init():42→GetQuickButtonsApi:47、GetRecordDetailApi:53;详情页起 10s 报警轮询(DetailPageView.xaml.cs:91-120→GetHouseCropAlarmApi)。PhotoPageViewModel(146 行,两版相同):GetPictureViewApi:88/GetSourcePictureViewApi:80,纯 HTTP。DishRecordViewModel(34)/AlarmPageViewModel(42):纯分页/日期状态容器,无业务调用。ChartPageViewModel(252,两版相同):环境曲线 RefHistroy():206→GetHouseEnvironmentListApi。HouseSettingPageViewModel(26):SettingSystemApi:17+GetSettingHouseApi:18,纯 HTTP。ServiceMonitorViewModel(192,新增,只读):每 2s 跨读 ivf_tl_Control.AppData.Instance.GetMonitorSnapshot():77,无下发控件;⚠ StaleSeconds=30(:28)、堆积阈值(:112-116)标 [D10] 占位、[M7] 运行时未验证。UnifiedConfigViewModel(85,新增):只写本地层 App.config(IP/端口/盘符/tlNum/语言/凭据),SaveAll():61 凭据 SaveEncrypted 加密;⚠ :60 返回值恒 true 占位(异常被 Helper 吞,不反映真实成败);数据库层项本页只读。DebugCalibrationAdapter.cs(55,新增):无运行逻辑,仅数据类型;注释说明旧 DebugSerial/CameraAdapter 已退役删除。合并后 control 跑在 operate 同进程,operate 三种方式直连 control。拆双进程时全部要改成 IPC/HTTP:
| # | file:line | 直连方式 | 拆进程后改成 |
|---|---|---|---|
| 1 | MainWindow.xaml.cs:89 | ControlAppData.Login() 同账号透传 |
启动独立进程 + 透传凭证 |
| 2 | MainWindow.xaml.cs:100 | 直写 ControlAppData.LogService.Pan |
启动参数/进程内配置 |
| 3 | MainWindow.xaml.cs:103,121 | new StartMain()+StartRun() 进程内跑 control |
拉起 control.exe 并等就绪 |
| 4 | MainWindow.xaml.cs:110,112 | HAL.Instance.Log/.ScanDevices() |
移入 control 进程自做 |
| 5 | HouseDebugPageViewModel.cs:256,257 | HAL.GetHouseGate().Acquire 借串口 |
跨进程借用协议(让出/恢复采集) |
| 6 | BufferDebugViewModel.cs:163,164 | HAL.GetHouseGate().Acquire 借串口 |
同上 |
| 7 | ServiceMonitorViewModel.cs:77 | ControlAppData.GetMonitorSnapshot() 直读 |
HTTP/IPC 拉快照 |
| 8 | MainPageViewModel.cs:768 | 直写 ControlAppData.LastHttpOkAt 心跳 |
跨进程上报通讯心跳 |
全目录已确认:其余 ViewModel 无 HAL/ControlAppData 直连,只走 HTTP。 借用语义:前台
Acquire(OperateDebug)触发 control 采集让路(协作式),复用同一物理句柄,Dispose即归还恢复采集——详见control-逻辑与配置全景.md§6.2。
ivf_tl_Services/HttpHelper.cs,1580 行,单例)AppData.cs:80 {urlIp}:{urlPort}/(经 AppConfigHelper 容错读,缺键回默认);Init 建 HttpClient(强制 Tls12,ExpectContinue=false)后立即 Login()。ServiceTimeout=12s(:42,HttpClient 整体)、AsyncTimeout=10s(:39,每次 SendAsync 的 CTS)。任何失败/超时直接返回 null,各 Api 吞异常返默认。GetToken():1348 缓存 token,每请求加头 token。callWebService 重载(无 body / JSON / Dictionary→Form)+ callWebServiceNoToken → 全汇聚 HttpClientSendAsync:1449。HttpClientSendAsync:1449-1497 取 OperationLogContext.TraceId ?? NewTraceId() 写请求头 traceId(:1460,与 Java 网关对齐,实现 C#→Java 链路串联)+ Stopwatch 计时 + 四类分支统一 SafeOpLog(module=HTTP,operation=接口路径,output>2000 截断,全 try 兜底)。登录 /api/gateway/auth/login(:1322/1354);天平 起/停 …/balance/startBalance(:191)/stopBalance(:215);在培列表 …/getHouseCultureList(:246);皿 增 addCultureRecord(:279)/结束 endCultureRecord(:308)/更新 updateCultureRecord(:332);图片视频 getPicturesByRecordId(:364);记录详情 getRecordDetail(:400);切层 switchVideoPictureLayers(:440)/switchVideoLayerByPicture(:985);快捷/时间按钮 …/getButtons(:468/497);仪器设置 …/setting/data(:529);系统设置 …/setting/system(:563)/更新(:595);版本 getVersionBySn(:619);舱室设置 …/setting/house(:651)/更新(:681)/调试回写 …/house/debugging(:780)/well 更新 …/house/well/update(:808)/对焦 …/house/focus/setting(:835)/立即拍照 …/house/immediately(:866);通用设置 …/setting/common(:719)/更新(:751);光照更新 …/lights/update(:894);仪器时间 …/tlInfo/time(:927);字典 queryDictionaryByType(:960);视频时间轴 getVideoTimeLine(:1008);环境列表 …/getHouseEnvironmentList(:1033);标记去向 markEmbryoDestination(:1058);皿记录 查/数 getEmbryoCultureRecord(Num)(:1081/1107);告警 数/历史 getAlarmNum(:1135)/getAlarm(:1161);图片视图 getPictures(:1189)/原始图 getSourcePictures(:1215);按 id 取皿 getCultureRecordById(:1241);静音 muteAlarm(:1267);裁剪告警 getHouseCropAlarm(:1290);文件下载(GET) DownLoadFileAsync(:97/138)。
接口清单与基准无增删,仅行号因埋点偏移。
userName/tlNum 明文读;passWord 经 CryptoHelper.Decrypt 回填(LoginWindow.xaml.cs:36-39)。AppData.SetApp/setAppConfig(AppData.cs:187-228,XmlDocument 直改 ivf_tl_Operate.dll.config)写 userName/tlNum 明文、passWord 加密。Helpers/CryptoHelper.cs —— DPAPI ProtectedData,LocalMachine 作用域,附加熵 "ivf_tl_operate_M5_02",密文前缀 enc:+Base64;Encrypt/Decrypt/IsEncrypted 幂等、失败回退原值不抛。AppConfigHelper.MigratePlaintextCredentials()(:88-126)启动时一次性把明文 passWord/engineerPwd 加密回写(幂等)。engineerPwd 默认 tl13579(AppConfigHelper.cs:20-23),GetEngineerPwd():129 解密取用。Helpers/AppConfigHelper.cs 容错读写(缺键返默认,不裸 NPE)。文件 ivf_tl_Operate/App.config。「基准」= 是否在基准版 临时文件/.../App.config(基准仅 11 键、无加密、无 oplog、无 control 业务键)。
🟢 2026-06-23 配置收敛(本表为收敛前历史快照,差异见下):① 共享连接键 outInter/urlIp/urlPort/mqttIp/mqttPort/kfkaIP/kfkaPort 已从
ivf_tl_Operate/App.config迁出到 operate 输出根的唯一数据源tl-shared.config(operate/control 经<appSettings file=>合并读);② 表中那批 CCDError/csTime/gbTime/VentNum/VentPre/VentWaitTimeB/VentWaitTimeD/AutoWaitTime/CCDAutoWaitTime/CCDFailedWaitTime/CCDFailedNumber/QueuAir 是 operate 死副本(operate 不读、只 control 读),已从 operate App.config 删除(control 自己那份保留)。收敛后 operate App.config 只留:autoFocus/userName/passWord/engineerPwd/tlNum/houseEnabled/Language/StopPro/cacheDisk/controlPort/controlExePath。详见specs/2026-06-23-配置收敛-operate-control连接组单一数据源-design.md。
| key | 现值 | 类别 | 基准 / 合并新增 |
|---|---|---|---|
| autoFocus | 0 | 业务(下位机换气开关) | 基准有 |
| outInter | 0 | 连接(0内网/1外网) | 基准有 |
| userName | admin | 凭据 | 基准有 |
| passWord | 启动迁移为 enc: |
凭据 | 基准有(原明文,合并加密) |
| engineerPwd | enc:(默认 tl13579) |
凭据 | 合并新增 |
| tlNum | 20230411 | 业务(设备号) | 基准有 |
| urlIp | http://127.0.0.1 | 连接 | 基准有(原 192.168.1.92,合并改值,需现场核对) |
| urlPort | 10010 | 连接 | 基准有 |
| mqttIp | 192.168.0.108 | 连接 | 基准有(原 192.168.1.92,合并改值) |
| mqttPort | 1883 | 连接 | 基准有 |
| kfkaIP / kfkaPort | 192.168.0.108 / 9092 | 连接(oplog) | 合并新增 |
| houseEnabled | 空 | 业务(禁用舱) | 基准有 |
| Language | Chinese.xaml | 业务 | 基准有 |
| CCDError/csTime/gbTime/VentNum/VentPre/VentWaitTimeB/VentWaitTimeD/AutoWaitTime/CCDAutoWaitTime/CCDFailedWaitTime/CCDFailedNumber/QueuAir | 见值 | 业务(control 换气/CCD) | 合并新增(并入的 control 键) |
| StopPro | 15 | 业务(关机倒计时) | 合并新增(control) |
| cacheDisk | C | 业务(缓存盘,MainWindow:96 透传 control) | 合并新增(control) |
含义见
control-逻辑与配置全景.md§8.1(这些 control 业务键由 control 端消费)。operate 端实际只读 outInter/urlIp/urlPort/mqtt/kfka/userName/passWord/engineerPwd/tlNum/Language/houseEnabled/autoFocus/cacheDisk。
control 全景管不到 operate 调试页,这一节是另一半文档的存在理由。降级根因统一:
control/IvfTl.Hardware/Impl/SerialChannelImpl.cs——control 端 Commander 缺对应 builder,HAL 实现"不臆造字节"返回桩值,VM 层据返回值给提示。
✅ 2026-06-23 更新:M-01/M-02/M-03 已修复并真机验证(TDD red→green + 非破坏性回环)——control 端补齐 3 个 E方 builder + ComBin Wait + SerialChannelImpl 去桩,见
进度/待验证清单.md同日段。下表前三行标 ✅已修复。M-04 存图经代码核查等价(24bpp/原生尺寸/canonical Y翻转,同权威 af ImageConverter)、M-05(0x12 帧长合并回归)、M-06(按 well 焦点零点)均已修复/定论(详见 §8.2 + 待验证清单)。
| 模块 | 操作 | 基准行为 | 现状(file:line) | UI 提示 | 风险 |
|---|---|---|---|---|---|
| 对焦调试 | 写舱室排气阀时间 ✅已修复 | WriteEEPROOpenVentTimeWait 真下发 |
Serial.WriteOpenVentTimeWait→_com.WriteEEPROOpenVentTimeWait(SerialChannelImpl.cs:130 已去桩;control 补 CreateWriteEEPROOpenVentTimeCommand 地址 00 03 08) |
— | 已解除:真机回环验证 舱9 200→201→200 / 舱8 90→91→90 PASS |
| 对焦调试 | 读舱室排气阀时间 ✅已修复 | ReadEEPROMVentWait 真读 |
Serial.ReadOpenVentTimeWait→_com.ReadEEPROMVentWait(SerialChannelImpl.cs:137 已去桩;control 补 CreateReadEEPROMVentNum) |
— | 已解除:真机读回真实值(200/90),非旧 -1 桩 |
| 缓冲瓶调试 | 写灯光亮度 EEPROM ✅已修复 | WriteEEPROMLightNumWait 真写 |
Serial.WriteLightBrightnessWait→_com.WriteEEPROMLightNumWait(SerialChannelImpl.cs:143 已去桩;control 补 CreateWriteEEPROMLightNum 地址 00 05 34) |
— | 已解除:真机回环 舱8 灯光 500→501→500 PASS |
| 对焦调试 | 调试页存图 ✅代码核查等价 | camera.SavePic(name,w,h)→厂商 MVCAPI.SavePic(buf,w,h,name) |
Cam.SavePic→CameraImpl.SavePic 丢弃 w/h→Camera.SaveBmpPic(name)=24bpp+原生尺寸+RotateNoneFlipY+按扩展名存(CameraImpl.cs:148-153) |
❌ 无提示(实现透明替换) | 已解除:朝向逻辑与权威 af ImageConverter 逐字一致(Y翻转=全系统正确朝向);忽略入参 w/h 正确(缓冲=相机原生尺寸);width=1600→1600*3=4800 四字节对齐,整块拷贝无错行。与不透明 native 厂商编码器逐字节一致既不可能也无必要(=M-04) |
WriteWellHorizontalPosWait/WriteScanStepWait/WriteOpenIntakeTimeWait 因旧栈写命令无显式成功出口,"阻塞收到回复即 return true",未把回包状态字传播给调用方(SerialChannelImpl.cs:106-118,接口注释 ISerialChannel.cs:54-65)。有下发,但成功与否未传回。属 M-05 残留(非回归,基线 operate 同样无条件 true)。control/ivf_tl_SerialHelper/Util/Commander.cs CustomProtocolLength 对 0x12 写E方回包帧长设成 6(合并回归;合并前 operate 基线=12),只读前 6 字节 → 把数据字节 [4] 误当状态字(非0→误判失败)、ORC 错位、且残留 6 字节污染紧接的下一次读(=M-01/02/03 验证时"写后读垃圾值"现象的根因)。真机 raw 抓包实证 0x12 回包确为 12 字节(舱8/舱9 一致,回包 [3]=0x0C 自证),改 control 帧长表 0x12→12。TDD:ivf_tl_SerialHelper.Tests/CustomProtocolLengthTests.cs red→green(0x12=12 + 整表对齐基线,22 单测过);真机回环"紧凑写→立即读、无丢帧 workaround"舱8/舱9 各 12 轮 24/24 全干净(旧码此处必出 -1/垃圾)。修复后 Channel 既有 receivedBuffer[lenght-2] 状态字检查也落到正确位置 [10]。详见 进度/待验证清单.md M-05。SerialChannelImpl.SendWait 返回 null(:61-66):裸帧通道未实现(TODO M2),当前调试页未用,仅影响未来扩展。ReadWellFocusZeroWait 已修复(M-06):此前 control 端忽略 well 入参恒读 well-1(ComBin.ReadEEPROMvertMtStartPulseWait 硬编码 CreateReadEEPROMvertMtStartPulse(1));builder 早支持 case 1-16(地址 0x08+4*(well-1),同 autofocustool 权威表)。改 ComBin 加 well 参(默认1,SerialBin 舱级读不变)+ SerialChannelImpl 传真 well。真机集成 red→green:各 well 修前全返回 well-1(舱9恒80200/舱8恒74600)→ 修后 per-well 各异(与 raw 抓包诊断逐 well 吻合)。对 autofocus Z 电机零影响:消费方 CalibrationEngine 粗对焦用固定中心 90000、eepromZ 未参与 Z 定位、所有 Z 移动恒 ClampZ[0,125000]。详见 进度/待验证清单.md M-06。ServiceMonitorViewModel 阈值占位:StaleSeconds=30、上传堆积阈值标 [D10] 占位、[M7] 运行时未验证。UnifiedConfigViewModel.SaveAll 恒返回 true(:60-82):异常被 Helper 吞,返回值不代表真实保存结果。CameraImpl.SetGain 返回 -1(control/IvfTl.Hardware/Impl/CameraImpl.cs:69-75,TODO M2):旧 Camera 未暴露独立增益设置(增益随 Init 固定),与 SendWait/ReadWellFocusZeroWait 同性质的待验证桩。当前调试/采集链路不调它,自动对焦标定若需调增益再补 native 包装。Helpers/ 整目录新增:AppConfigHelper(配置容错)、CryptoHelper(DPAPI 加密)、ClickTrailLogger(全局点击层日志)。App.xaml.cs 新增:凭据迁移、操作日志初始化、点击层安装、UI 异常按签名 10s 节流(:184-220,防 8GB 日志复发)。ServiceMonitorView(只读监控)、UnifiedConfigView(本地配置)、内置软键盘。RemoveAt(Count-1) 盲删(误删 AdaptiveStyles 致 8GB 日志);合并改按引用/按 /Language/ 精确移除(App.xaml.cs:265-281)。ConfigurationManager.AppSettings[...](缺键 NPE/FormatException);合并改 AppConfigHelper.GetString/GetInt(缺键回默认不崩)。| 线程/任务 | file:line | 形态 | 职责 |
|---|---|---|---|
| control 后台托管 | MainWindow.xaml.cs:67-132 | Task.Run 一次 | 登录后起 control(内部阻塞常驻) |
| 胚胎详情报警轮询 | DetailPageView.xaml.cs:91-120 | Task.Run+while+Sleep(10s) | operate 唯一常驻轮询:每 10s GetHouseCropAlarmApi 刷报警;vm==null 退出 |
| MQTT 订阅回调 | AppData.cs:138-143 | 事件回调 | broker 推送舱室实时数据(登录建立) |
| 日志洪流节流 | App.xaml.cs:184-205 | 静态字典 | 同签名异常 10s 内只放行一条(合并新增) |
| 按钮短任务 | 多页 | Task.Run 短任务 | 调试/查询点击不卡 UI,用完即结束 |
operate 内无 DispatcherTimer/Timers.Timer/显式 new Thread;常驻后台只有"详情页 10s 轮询"+"control 托管线程"。
AppData.cs:91-111 #if DEBUG 外网覆盖:Debug 编译下连续 4 次覆盖 BaseUrl,最终写死 http://test-gateway.aivfo.com:36000/(测试外网),无视 App.config。真机验证/抓真实问题必须用 Release,否则连到测试环境。(与基准一致,非合并引入)AppData.cs:84-90 outInter==1 外网分支:Release 下也会把 BaseUrl 切 test-gateway.aivfo.com:36000、MqttIp 211.149.139.131。当前 outInter=0 走内网,但这是个地址打外网的开关。HttpHelper.GetMp4():75-94 死代码:硬编码外网 FastDFS 地址 + 桌面绝对路径,无调用方(测试残留),建议删。#if DEBUG 本地绝对路径(AppData.cs:243-247、App.xaml.cs:243-246):Logo/语言文件指向 C:\PersonalSpace\work\...,仅开发机有效。urlIp=127.0.0.1/mqttIp=192.168.0.108(App.config,合并改值):需现场确认实际网关 IP(注释已标 [M7] 现场核对)。OperateHwTest = 测试代码,非交付件(ivf_tl_operate_2.0/OperateHwTest/Program.cs,与 ivf_tl_Operate 平级的控制台项目):internal class Program,真机硬件闭环测试 CLI,子命令 scan/motor/http/camera,复用 operate 真实 ivf_tl_Entity.ComEntitys.ComBin 与 HttpHelper 驱动真机;硬编码 admin/123456 与 7 舱→COM 口映射、电机脉冲安全钳位。属测试/诊断工具(性质同 control 侧 ivf_tl_ControlTest 老壳),交付打包不含、上线前确认随测试资料归档或排除,勿当产品功能。App_Exit 空体、去掉了 control 的 Environment.Exit——拆分后 operate 关闭只关 UI,control 进程续命;需补对称停机入口(参 control 全景 §九.5)。CreateWriteEEPROOpenVentTimeCommand / 读排气阀 / CreateWriteEEPROMLightNum)+ 真机核对字节即可接通;存图需真机核对 SaveBmpPic 与 MVCAPI.SavePic 落盘一致性。