Files
FG2608061/差异文档.md
2026-08-19 17:02:08 +08:00

11 KiB
Raw Permalink Blame History

华晓AGV管理系统 源码与现场应用差异报告

生成日期:2026-08-19 比对方法:将「现场运行的二进制」与「CODE 源码重编译产物」用同一版本 ILSpyilspycmd 11.0.0.9375)、同一参数分别反编译为 C#,再逐类逐行 diff。两侧均带 PDB,局部变量名可还原,diff 结果即真实源码差异。 结论先行:差异全部集中在主程序 exe 和 HxBusiness.dllBllSql.dll 零差异。所有差异均属于同一主题——「第三方交管(路权申请/归还)功能的完善」+「地标拖动调整坐标的小工具」+「日志增强」。


1. 比对对象与基线

现场(基准) CODE 源码
华晓AGV管理系统.exe 2023-09-18 编译,2,212,352 字节 快照 20230901,重编译 2,201,088 字节
BllSql.dll 2023-09-02 编译 同期
HxBusiness.dll 2023-09-15 编译 快照 20230901
其余 20 个第三方 DLL 20152019 MD5 全部一致,无需处理
  • 现场目录自带的 华晓AGV管理系统.zip 内是 2023-09-02 的旧 exe 备份,用它与源码重编译产物做了方法校准:仅 2 个文件 10 行差异(源码略新于 9/2 备份),证明比对方法可靠。
  • 现场 exe 为 Debug|x86 / .NET Framework 4.5.2 构建,与 CODE 工程配置一致。
  • 现场是用 VS2022 (17.x) 工具链构建的(Designer 生成代码版本号为 17.x,资源序列化格式与新工具链一致)。

2. 程序集级差异总览

程序集 差异 说明
BllSql.dll 反编译逐行一致,源码无需任何改动
HxBusiness.dll 2 处 ApiModel 新增属性;ByLeaved 参数校验放宽
华晓AGV管理系统.exe 新增 2 类 + 修改 4 文件 + 2 处生成器版本号 详见下文

3. HxBusiness.dll 差异明细

3.1 Model\ApiModel.cs — 新增属性

public int AutoTime { get; set; }   // 自动归还路权秒数,0=手动归还

与现场 Config\ApiModel.json 中新增的 "AutoTime": 30 对应。

3.2 BusinessManage.csByLeaved 校验放宽

// 旧(源码):
if (string.IsNullOrEmpty(agvid) || string.IsNullOrEmpty(rfid))
// 新(现场):
if (string.IsNullOrEmpty(agvid))

原因:交管自动/手动归还场景下 rfid 可能为空(TrafficCtrl 中 Agv_Land 可能返回 0),不应拒绝请求。

4. 华晓AGV管理系统.exe 差异明细

4.1 新增类 A17168\TrafficModel.cs

public class TrafficModel
{
    public string areaCode { get; set; }   // 路口(交汇区)地标编号
    public int agvId { get; set; }         // 当前占用该路口的AGV0=空闲
    public DateTime InArea { get; set; }   // 进入路口时间
}

4.2 新增类 A17168\TrafficCtrl.cs — 第三方交管自动归还监听线程

  • Listen():死循环(1s 周期)。当 apiModel.AutoTime > 0waitRfidList 非空时,遍历 Frm_A17168.autoLeavedDic,对占用超过 AutoTime 秒的路口调用 businessCtrl.ByLeaved(agvId, 当前地标, areaCode) 自动归还路权,成功后清零 leavedDic[agvId]trafficModel.agvId,写"放行日志X"(插件日志目录)。
  • Agv_Land(agvid):私有辅助,从 Func.AgvInfo 取该 AGV 当前地标。
  • 异常写"异常日志"(插件日志),日志文案:第三方交管监听线程异常!

4.3 A17168\Frm_A17168.cs — 3 处

  1. 新增静态字段:
public static int TraffAutoTimet = 0;
public static List<TrafficModel> autoLeavedDic = new List<TrafficModel>();
  1. 构造函数中 businessCtrl = new BusinessManage(); 之后新增初始化:按 apiModel.waitRfidList 逗号拆分,为每个路口建一个 TrafficModel 放入 autoLeavedDic,并读取 TraffAutoTimet = apiModel.AutoTime
  2. Frm_A17168_Load 中启动 UPDateDBList.UpDateDb 线程之后,新增启动交管监听线程:
Thread thread2 = new Thread(TrafficCtrl.Listen);
thread2.IsBackground = true;
thread2.Start();

4.4 A17168\Cls_A17168.cs — 两个数据线程方法(AGV_Data 网口型 / AGV_Data2 S7-200型)同步修改

注:diff 中大量 agvInfo→tempnum→location_temp 为现场源码的变量改名(PDB 还原的真实命名),无语义影响,但为达成"反编译零差异"验收,回灌时同步改名。

真实语义差异(两个方法对称出现,编号 1x 为 AGV_Data2x 为 AGV_Data2):

  1. 调试日志埋点:读到地标后写 "=========》(11/21):" + 地标 到"调试日志";进入 waitRfid 分支写(12/22);请求放行成功写(13/23);进入 leavedRfid 分支写(14/24);释放成功写(15/25)。
  2. 放行前日志地标 + "开始请求放行" / "开始请求释放" 写入"放行日志{AgvID}"(插件日志)。
  3. 放行成功后登记交管占用(原来 if (flag && WriteInfo(...)==0) 拆为嵌套):
if (flag)
{
    TrafficModel m = Frm_A17168.autoLeavedDic.Find(_ => _.areaCode.Equals(location_temp.ToString()));
    if (m != null) { m.agvId = temp.Agv_ID; m.InArea = DateTime.Now; }
    WriteTxt.SaveLog1(location_temp + "路口添加" + m?.areaCode + "(" + m.agvId + ")", "放行日志" + temp.Agv_ID, "插件日志");
    if (WriteInfo/WriteVW(...) == 0) { /* 原放行逻辑 */ }
}
  1. 归还接口第 3 参改变ByLeaved(agvid, 当前地标, num3(上次放行地标))ByLeaved(agvid, 当前地标, (当前地标-1))(离开地标 = 进入地标+1 的约定)。
  2. 归还成功后清除交管占用autoLeavedDic 中对应 TrafficModel.agvId = 0
  3. 报警处理异步化Thread.Sleep(100); Warn_Deal(_Plc)(...) 改为 ThreadPool.QueueUserWorkItem(delegate { Thread.Sleep(100); Warn_Deal(_Plc)(temp, sWarn); });,避免阻塞采集循环。
  4. 仅 AGV_Data2:地标变化时删除了 Func.Change_Rec(...) 调用;Location_Log 插入由同步 bBllBase.ExecuteNonQuery(sql) 改为 UPDateDBList.sqlList.Add(item) 异步批量入库。
  5. 变量声明顺序/命名调整(templocation_tempnum2~num5 重排)——纯改名,随语义项一并同步。

4.5 Cls\Func.cs — 新增"Ctrl+拖动地标改坐标"小工具

  1. 新增静态字段:moveFlagxPosyPos
  2. CreateLandMark(路口地标创建分支)为 label 增挂 3 个事件:MouseUp += label_UpClick; MouseDown += label_DownClick; MouseMove += label_MoveClick;
  3. 新增 4 个私有静态方法:
    • label_DownClick:按下记录起点,moveFlag=true
    • label_MoveClick:拖动时移动地标所在 Panel
    • label_UpClick:松开时若按住 Ctrl 且已登录管理员,弹窗确认后调用 UpLocation
    • UpLocation(rfid,x,y)UPDATE [LandMarkInfo] SET [Loc_X]=x,[Loc_Y]=y WHERE [Loc_ID]=rfid

4.6 Cls\Path_Reset.cs — 双击复位路口时手动归还路权

  1. label12_DoubleClick 开头新增 ClearOtherLand(array[1]);
  2. 新增 ClearOtherLand(int land):在 autoLeavedDic 中找到该路口且被占用(agvId≠0)的记录,调用 businessCtrl.ByLeaved(agvId, land, areaCode) 手动归还,成功后清零,写"手动释放/路口已手动归还"日志(插件日志)。
  3. 文件头新增 using AGVSystem.A17168;

4.7 生成器版本号(纯装饰,为达成零差异同步)

  • Properties\Resources.Designer.csStronglyTypedResourceBuilder 版本 16.0.0.017.0.0.0
  • Properties\Settings.Designer.csSettingsSingleFileGenerator 版本 16.10.0.017.6.0.0

5. 配置文件差异(不随 bin 替换,仅记录)

文件 差异 处理
Config\ApiModel.json 现场版(2024-03-04waitRfidList/leavedRfidList 由 9 个路口扩到 25 个,新增 "AutoTime": 30(行尾带 // 注释,Json.NET 可解析) 现场为准,替换 bin 时严禁覆盖;建议将 CODE bin 内该文件同步为现场版便于本机调试
华晓AGV管理系统.exe.configinfo.iniagvinfo.iniitem.ini 无差异 不动
Nancy.Hosting.Self.dll 现场没有此文件;现场代码已不使用 NancyHost 自宿主(BusinessManage 中相关代码已注释) 替换包中不要包含此 DLL

6. 与整合无关的说明(查漏补缺结论)

  1. 用户提供的 dnSpy 反编译 CODE(反编译CODE\ 目录)与本报告的 ILSpy 反编译结果核对一致,未发现 dnSpy 导出遗漏的类型;其中 SqlHelperParameterCacheE_StateRequestLeavedModelSendModelChannelLocation_Log 等"多出来的文件"只是 dnSpy 按类拆分所致,源码中都存在。
  2. CODE 中的 Creat_Task.csCls\Func - 副本 (2).cs 未被 csproj 编译,现场 exe 中也无对应类型,保持现状即可。
  3. 源码快照(20230901)略新于现场 zip 备份中 9/2 的 exe:多了"AGV经过地标"地标日志、order by id、部分路口数组扩容——即源码基线本身没有丢内容,缺的只是 9/2–9/18 的增量。

7. 回灌与验收

  • 回灌范围:4.14.7 全部 + 3.1–3.2,共 10 个源文件(新增 2 个、修改 8 个,含 csproj 注册与 2 个 Designer 版本号)。
  • 验收标准:重编译后,用同一 ilspycmd 反编译新 exe / HxBusiness.dll / BllSql.dll,与现场反编译结果 逐行零差异(反编译器自动生成的 csproj 除外,其差异仅为本机路径)。
  • 替换清单(复制到现场目录):华晓AGV管理系统.exe华晓AGV管理系统.pdbHxBusiness.dllHxBusiness.pdbBllSql 无差异可不换)。
  • 回滚:替换前备份现场原文件;现场目录自带 9/2 的 zip 备份可作最后手段。

验收结果(2026-08-19 已完成)

程序集 反编译比对结果
华晓AGV管理系统.exe 53 个类型全部逐行一致TrafficCtrl.Listen 连 IL 字节长度都已对齐)
HxBusiness.dll 全部逐行一致
BllSql.dll 全部逐行一致(源码未改动,重编译即一致)

细节备注:

  1. 现场源码风格已在回灌中还原——continue 不带大括号(带括号会多一个 nop 字节改变 IL 标签号)、TrafficCtrl 的 foreach 采用两个独立守卫 ifFrm_A17168 初始化直接对 Split(',') 结果 foreach(不引入中间变量)。
  2. Func.label_UpClick 现场 IL 采用"正向 if 包裹 + return"结构(297 字节),回灌版为等价的"取反守卫 return"结构(293 字节),两者反编译 C# 完全一致、行为完全一致,仅方法内部 IL 编排不同,不影响验收。
  3. 之前 diff 中大量 agvInfo→tempnum→location_temp 的"改名"是反编译命名假象:现场代码因 lambda 闭包捕获把真实变量名保留进了元数据,回灌 lambda 后两侧命名自动对齐,非真实源码差异。