6.4 插件扩展与脚本自动化


6.4 插件扩展与脚本自动化

本节摘要:组件式与服务端是重型装备,日常需求里的大头其实用轻武器就能解决。本节讲两条轻量路线:插件把一个功能挂进桌面端菜单,脚本把重复批处理交给机器。二八定律在这里最灵验——八成的零散需求,用两成的学习成本覆盖。

插件:借宿主的壳,装自己的货

科室内业人员最常提的需求长这样:"能不能加个按钮,点一下就把当前图层的拓扑问题全查出来?"他们不想学新软件,就想在天天用的桌面端里多一个按钮。这正是插件的用武之地——宿主程序提供界面、数据管理、地图显示这些重资产,插件只写业务增量。

插件的运行机制一句话讲清:宿主启动时扫描插件目录,发现实现了约定接口的动态库,调用其初始化方法,插件趁机把自己的命令注册进菜单。画成流程:

流程图里最重要的角色是"宿主上下文"——初始化时宿主递给插件的那个对象。拿它才能取到当前地图、当前图层、当前选择集。插件代码里最常见的错误不是逻辑错,是绕过上下文自己另开数据连接,结果用户在界面里改了数据,插件读到的还是旧库。

一个最小可用的插件骨架如下,注册一个"统计当前图层要素数"的命令:

using System.Windows.Forms; public class CountPlugin : IMapGISPlugin { private IApplication app; // 宿主上下文 初始化时拿到 public string Name => "图层统计"; public string Caption => "统计当前图层要素数"; public void Initialize(IApplication host) { app = host; // 存住上下文 这是插件的命根 app.Commands.Register(this); // 向宿主注册命令 } public void Execute() { var layer = app.ActiveMap.GetLayer(0); // 取当前激活图层的第0层 if (layer == null) { MessageBox.Show("请先打开一个地图并激活图层"); return; } int n = layer.FeatureCount; // 经宿主上下文取数 保证是最新状态 MessageBox.Show("图层 " + layer.Name + " 共 " + n + " 个要素"); } public void Uninitialize() { /* 释放自建资源 上下文由宿主管 */ } } // 编译为动态库放入插件目录 重启宿主 菜单出现新命令 // 输出:点命令 弹窗 图层 耕地图斑 共 38421 个要素

插件的开发循环比组件式短得多:改代码、编译、拷贝动态库、重启宿主、点菜单验证。五个动作两分钟一轮。唯一的纪律是版本对齐——宿主升级后插件要回归测试,接口签名变了就得改代码重编,这是借壳的代价。

脚本:把重复劳动交给机器

脚本路线的适用特征更明确:流程固定、无需界面、按批或按定时执行。判断口诀——"同一个操作做过第三次,就该写成脚本了"。

数据进厂环节的经典场景:测绘队每周交一批 CAD 宗地图,转要素类、统一属性字段名、算椭球面积、写质检标志,四步工序对几十个文件重复执行。手工做一晚,脚本做一分钟:

# 概念演示:宗地图批量进厂脚本(桌面端脚本接口 示意写法) import os import mapgis_dev as mg # 桌面端脚本开发模块 SRC = "宗地图收件目录" # 本周收件 OK = "进厂合格目录" steps_log = [] # 过程留痕 供质检回看 for name in os.listdir(SRC): if not name.endswith(".dwg"): continue # 只处理CAD文件 path = os.path.join(SRC, name) fc = mg.import_cad(path, target_gdb="耕地保护库") # 步骤1 转要素类 fc.rename_fields({"地块号": "宗地编号", "权利人": "权属单位"}) # 步骤2 字段统一 fc.add_area_field("椭球面积") # 步骤3 法定口径面积 bad = fc.check(拓扑="悬挂,缝隙", 面积="负值") # 步骤4 质检 if bad.count == 0: fc.move_to(OK) # 全过 进合格目录 steps_log.append((name, "通过", fc.count)) else: steps_log.append((name, "退回", str(bad.detail))) # 问题清单回传测绘队 for row in steps_log: print(row) # 输出示例: # (宗地007.dwg, 通过, 12) (宗地008.dwg, 退回, 悬挂点2处 缝隙1处) (宗地009.dwg, 通过, 8) # 定时执行:挂到操作系统的计划任务 每周五晚跑 周一上班看结果

脚本的两个工程习惯决定它是资产还是负债。留痕:每次运行把输入、输出、退回原因写成日志,出了争议有据可查,上面的 steps_log 就是为此。进版本库:脚本散落在各人机器桌面上的团队,脚本死了没人能救;进了版本库,人走了脚本还在跑。

学习目标

阅读完本节,你应当能够:

  1. 描述插件从加载、注册、执行到清理的完整生命周期
  2. 编写带宿主上下文的最小插件并完成部署验证
  3. 把一个重复三遍以上的操作改写成批处理脚本
  4. 为脚本建立留痕与版本管理两个工程习惯
  5. 判断一个需求该走插件还是脚本,并说出各自代价

两条轻量路线的合流

插件与脚本常在一个科室里合流成"个人工具箱":白天内业用插件点按钮,夜里批处理靠脚本跑定时任务。它们共享同一套对象模型——6.2 啃下的四级结构在插件里是宿主上下文下的对象,在脚本里是模块直接给的对象。这就是本章把组件式放在最前面讲的原因:对象模型是三条路线公共的地基。

工具箱的积累是复利型的。第一年攒下十个插件五个脚本,第二年新同事入职直接继承整套工具,科室的产能就和别人不一样。第 7 章的行业案例里,那些"三天出一个成果"的标杆项目,背后几乎都有一个沉淀多年的工具箱。

⚠️ 常见坑:脚本没有失败处理,半夜跑到第三个文件崩了,剩下四十个文件没人管,周一来看"跑了一半"。批处理脚本必须有整体的事务观念——逐文件容错(单文件失败记录后继续)、末尾汇总报告(成功多少退回多少)、关键步骤可重跑(幂等设计,重跑不会重复入库)。

  • 借壳机制:宿主扫描、初始化注册、回调执行、清理退出,四拍子循环
  • 上下文是命根:插件取数必须经宿主上下文,另开连接必读到旧数据
  • 脚本判断口诀:同一操作做过第三次,就该写成脚本
  • 两个工程习惯:留痕日志、进版本库,决定脚本资产还是负债
  • 幂等设计:批处理可重跑,单文件容错,末尾必出汇总报告
  • 工具箱复利:插件加脚本年年沉淀,产能差距由此拉开

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U