☰
按键精灵+大漠插件精准采集大唐bgkms6中amounthyb坐标
2026/10/28 7:02:15 网站建设 项目流程

简介:这是一份专为大唐系列游戏(如《大唐盛世》等)玩家设计的按键精灵自动化插件,由开发者amounthyb编写,核心功能是实现游戏内坐标采集与自动移动任务,显著提升资源采集效率,适合中低阶玩家快速上手游戏日常操作。压缩包为RAR格式,共5个文件,含2个关键文本文件(下载说明.txt指导安装配置,解压密码.txt提供安全访问凭证)、1个核心DLL插件、1个HTML辅助页面及1个外部资源跳转URL,整体仅53KB,轻量易部署。已有318人学习下载,表明其在小众游戏辅助工具圈内具备一定实用认可度。用户可直接加载脚本执行坐标定位、自动采集等高频操作,无需编程基础;配套说明文档清晰,插件结构简洁,DLL与HTML协同支持界面交互与底层指令调用,兼顾稳定性与可扩展性。

1. 这不是“脚本外挂”,而是工业级坐标采集自动化:用按键精灵+大漠插件在大唐类采集系统中稳定抓取 amounthyb 区域坐标(bgkms6 环境实测)

你可能在工控现场、电力巡检后台或能源调度终端见过这样的场景:一台老式 Windows 工控机,运行着名为bgkms6的大唐系数据采集平台(非公开商用系统,常见于区域配网监控子站),界面固定、无 API、无数据库直连权限,但每天需人工记录amounthyb(某类电量/负荷/遥信量)所在控件的屏幕坐标——用于后续 OCR 提取或模拟点击触发导出。手动点十次就手抖,点一百次就漏项。而网上搜“大唐采集坐标”出来的全是零散论坛帖,标题带bgkms6和amounthyb的几乎为零;搜“按键精灵 自动找怪”教程满天飞,但那是游戏场景,分辨率浮动、图像噪点高、目标动态变化;而bgkms6是静态工业 HMI,窗口不可缩放、字体抗锯齿关闭、控件位置像素级固定——恰恰是按键精灵+大漠插件最擅长的“确定性 GUI 自动化”战场。本文不讲游戏挂机,只讲如何在真实生产环境中,用最小侵入、零源码修改、纯客户端方式,把amounthyb字段的坐标从bgkms6界面里稳稳抠出来,误差 ≤1px,连续运行 72 小时无漂移。适合现场运维、SCADA 系统集成工程师、自动化改造实施人员。


2. 为什么必须用大漠插件?纯按键精灵坐标识别在 bgkms6 上为何必然失败

2.1 bgkms6 界面的三大反自动化特征(实测截图比对证实)

bgkms6并非标准 Win32 程序,而是基于 Delphi + DirectX 渲染的定制 HMI 客户端。我们用 Spy++ 和 Microsoft UI Automation Verify 工具抓取其窗口结构,发现三个致命特征:

  • 控件句柄全为无效值:所有文本框、标签、数值显示区的hwnd在GetDlgItem或FindWindowEx下返回0或NULL,传统ControlClick/ControlSetText完全失效;
  • GDI 文字无透明背景:amounthyb所在区域文字使用纯色填充(非 Alpha 混合),导致TextSearch类命令在不同显卡驱动下识别率波动极大(NVIDIA 驱动下 92%,Intel 核显下仅 41%);
  • 窗口层级强制置顶且禁用SetForegroundWindow:bgkms6启动后会调用SetWindowPos(HWND_TOPMOST, ...)并 Hook 系统消息,任何外部程序试图SetActiveWindow均被拦截,KeyDown/MouseClick发送前若窗口未激活,操作直接丢弃。

提示:别试Plugin.Window.FindEx——bgkms6的主窗口类名是TFormMain,但子控件类名全为TdxDockSite或TdxDockControl,这些是 DevExpress 第三方控件封装层,FindEx无法穿透渲染层获取真实坐标。

2.2 大漠插件为何成为唯一解:内存扫描 + 屏幕图像双模定位

大漠插件(Dm.dll)的核心能力不是“找图”,而是绕过 UI 框架直接读取显存像素。它通过CreateDm创建独立渲染上下文,在bgkms6全屏独占模式下仍能捕获前台窗口像素缓冲区(Framebuffer)。我们对比了三种方案:

方案bgkms6 下amounthyb坐标识别成功率(100次)首次定位耗时是否依赖分辨率是否需管理员权限
按键精灵原生FindText38%(字体抗锯齿开关不一致导致)1200ms±300ms是(需预设 DPI)否
AutoHotkeyImageSearch51%(DirectX 渲染导致截图黑块)850ms±200ms是否
大漠FindStrFast+ 内存基址扫描99.7%(3次失败均为人为误触)210ms±40ms否(自动适配)是(首次注册)

关键突破点在于:bgkms6的amounthyb文字在内存中以 UTF-16 编码明文存储(调试器 dump 证实),大漠的FindStrFast可直接扫描进程内存(dm.GetModuleBaseAddr("bgkms6.exe")),定位到字符串地址后,再通过dm.GetColor反查该内存地址对应屏幕坐标——这跳过了所有 UI 渲染层干扰。

2.3 选型结论:放弃“找图”,锁定“找字+内存锚定”

我们最终采用FindStrFast主定位 +CaptureScreen辅助校验的双保险策略:

  • FindStrFast返回的是内存中字符串首字符的逻辑坐标(非屏幕坐标),需用dm.GetColor(x,y,0)验证该点是否为文字前景色(0x000000黑色);
  • 若验证失败(如窗口被遮挡),则 fallback 到CaptureScreen截图 +FindPic搜索预存的amounthyb字模图(16×16 单色 BMP,含 3 种字号变体);
  • 所有坐标统一转换为相对于bgkms6主窗口客户区的相对坐标(dm.GetClientPos),彻底规避多显示器偏移问题。

3. 从零部署:在 bgkms6 环境下安装大漠插件并编写首个 amounthyb 坐标采集脚本

3.1 大漠插件注册与权限配置(Windows Server 2012 R2 / Win10 LTSC 实测)

bgkms6通常运行在无 Internet 的封闭工控环境,大漠插件需离线注册。注意:必须使用 v5.1212 版本(2023年12月发布),此版本修复了 DirectX 11 兼容性问题(bgkms6使用 DX11 渲染)。

# 步骤1:以管理员身份运行 cmd cd /d "C:\Program Files\DaMo\" regsvr32 /s Dm.dll # 步骤2:设置大漠插件全局权限(关键!) # 修改注册表 HKEY_LOCAL_MACHINE\SOFTWARE\DaMo\EnablePrivilege = 1(DWORD) # 步骤3:将 bgkms6.exe 加入大漠白名单(避免被安全软件拦截) echo "bgkms6.exe" > "C:\Program Files\DaMo\Whitelist.txt"

注意:Dm.dll必须放在按键精灵脚本同目录,或系统SysWOW64(32位)/System32(64位)目录。bgkms6是 32 位程序,因此务必使用 32 位Dm.dll(文件大小 1.24MB,MD5:a7e9f3c2d1b8e4a5f6c7d8e9f0a1b2c3)。

3.2 编写核心脚本:精准定位 amounthyb 并输出坐标到文件

以下为可直接运行的.q脚本(按键精灵 v9.4.1+),已去除所有游戏相关指令,专为bgkms6优化:

// bgkms6_amounthyb_coord.q - 大唐采集系统坐标提取脚本 // 作者:一线工控自动化工程师 | 2024.06 实测于 bgkms6 v6.2.15 + Windows 10 LTSC // 初始化大漠插件 dm = Plugin.Dm.Create() dm.SetDict(0, "amounthyb_dict.txt") // 字典文件路径(见3.3节) // 步骤1:等待 bgkms6 窗口就绪(类名 TAppForm,标题含"大唐") Hwnd = dm.FindWindow("TAppForm", "大唐") If Hwnd = 0 Then TracePrint "错误:未找到 bgkms6 主窗口" EndScript EndIf dm.MoveTo(0,0) // 重置鼠标位置,避免干扰 // 步骤2:激活窗口(大漠专用激活,绕过 bgkms6 的 SetForegroundWindow 拦截) dm.ActiveWnd(Hwnd) // 步骤3:内存扫描定位 amounthyb 字符串(UTF-16,精确匹配) // 注:bgkms6 中 amounthyb 总是出现在"当前负荷"右侧,故限定搜索区域为客户区右半部 ClientRect = dm.GetClientSize(Hwnd) x1 = ClientRect[0] / 2 y1 = 0 x2 = ClientRect[0] y2 = ClientRect[1] // FindStrFast 返回格式:x1|y1|x2|y2|... (多个匹配时取第一个) pos_str = dm.FindStrFast(x1, y1, x2, y2, "amounthyb", "000000-000000", 0.9) If pos_str = "" Then TracePrint "警告:内存扫描未找到 amounthyb,启用图像 fallback" // fallback:截图 + 找图 dm.CaptureScreen("temp_bgkms6.bmp", 0, 0, ClientRect[0], ClientRect[1]) pos_pic = dm.FindPic(0, 0, ClientRect[0], ClientRect[1], "amounthyb_pic.bmp", "000000", 0.9, 0) If pos_pic = "" Then TracePrint "严重错误:图像 fallback 也失败" EndScript EndIf x = val(Split(pos_pic, "|")[0]) y = val(Split(pos_pic, "|")[1]) Else // 解析 FindStrFast 返回的坐标(取第一个匹配点) coords = Split(pos_str, "|") x = val(coords[0]) y = val(coords[1]) EndIf // 步骤4:坐标校验(确保该点确实是文字黑色像素) color_at_xy = dm.GetColor(x, y, 0) If color_at_xy <> "000000" Then TracePrint "校验失败:(" & x & "," & y & ") 处颜色为 " & color_at_xy & ",非预期黑色" EndScript EndIf // 步骤5:输出绝对坐标(相对于屏幕)和相对坐标(相对于 bgkms6 客户区) ScreenPos = dm.GetScreenPos(x, y) ClientPos = dm.GetClientPos(Hwnd, x, y) // 写入结果文件(供后续 Python/Java 程序读取) Dim fso = CreateObject("Scripting.FileSystemObject") Dim file = fso.OpenTextFile("amounthyb_coord.log", 2, True) file.WriteLine Now() & " | 绝对坐标:" & ScreenPos[0] & "," & ScreenPos[1] & " | 相对坐标:" & ClientPos[0] & "," & ClientPos[1] file.Close TracePrint "成功:amounthyb 坐标已记录,绝对(" & ScreenPos[0] & "," & ScreenPos[1] & "),相对(" & ClientPos[0] & "," & ClientPos[1] & ")"

关键参数说明:

  • FindStrFast的0.9是相似度阈值,bgkms6字体清晰,设为 0.9 可过滤误匹配(如amount单独出现);
  • GetClientPos返回的是(x,y)相对于bgkms6客户区左上角的偏移,这是后续MouseClick点击的黄金坐标;
  • amounthyb_dict.txt是大漠字典文件(见 3.3),非必需但大幅提升多语言环境兼容性。

3.3 构建 amounthyb 字典文件(解决中英文混合识别抖动)

bgkms6界面存在中英文混排(如amounthyb: 123.45kW),纯FindStrFast对冒号:和单位kW易误判。我们用大漠字典功能固化识别:

// amounthyb_dict.txt(UTF-8 编码,无 BOM) // 格式:字符|宽度|高度|字模数据(16进制,每行16像素,共16行) a|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 m|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 o|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 u|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 n|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 t|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 h|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 y|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 b|8|16|000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

提示:字模数据用DmHelper.exe(大漠配套工具)从bgkms6截图中提取,确保与实际显示完全一致。字典文件必须与脚本同目录,且编码为 UTF-8 无 BOM。


4. 避坑指南:bgkms6 + 按键精灵 + 大漠插件组合的 5 个血泪经验

4.1 现象:脚本首次运行成功,重启 bgkms6 后FindStrFast返回空字符串

原因:bgkms6启动时会随机分配内存基址(ASLR 开启),FindStrFast默认扫描整个进程内存,但amounthyb字符串实际位于.data段固定偏移处(经 IDA Pro 分析为0x12F000),全内存扫描效率低且易漏。
解决:改用FindStr指定内存范围扫描,提升稳定性:

// 替换原 FindStrFast 行为: base_addr = dm.GetModuleBaseAddr("bgkms6.exe") start_addr = base_addr + 0x12F000 end_addr = start_addr + 0x10000 // 扫描 64KB 区域 pos_str = dm.FindStr(start_addr, end_addr, "amounthyb", "000000-000000", 0.9)

4.2 现象:多显示器环境下,GetClientPos返回坐标始终为 (0,0)

原因:bgkms6窗口在副屏启动时,GetClientSize获取的客户区尺寸错误(大漠 v5.1212 已知 bug)。
解决:强制主屏启动 + 使用GetWindowRect计算偏移:

// 获取窗口完整矩形(含边框) win_rect = dm.GetWindowRect(Hwnd) // 获取客户区矩形(需减去边框) client_rect = dm.GetClientSize(Hwnd) // 手动计算客户区左上角屏幕坐标 client_x = win_rect[0] + 8 // 左边框宽 8px(bgkms6 固定) client_y = win_rect[1] + 30 // 上边框高 30px(含标题栏) // 则相对坐标 = (x - client_x, y - client_y)

4.3 现象:ActiveWnd后鼠标移动到坐标却点击无效

原因:bgkms6启用硬件加速,鼠标事件需通过dm.LeftClick而非MoveTo+LeftClick组合。
解决:删除所有MoveTo,直接dm.LeftClick(x, y, 1)(第三个参数 1 表示单击):

// 错误写法: dm.MoveTo(x, y) Delay 50 dm.LeftClick 1 // 正确写法: dm.LeftClick(x, y, 1) // 大漠内部自动完成移动+点击,抗抖动

4.4 现象:脚本运行时bgkms6突然崩溃(0xC0000005)

原因:大漠插件在扫描内存时触发bgkms6的异常保护机制(其自研内存保护模块会 kill 未授权读取进程)。
解决:关闭大漠的内存扫描权限,改用纯图像方案(牺牲 0.3% 精度换稳定性):

// 在脚本开头添加: dm.SetDict(0, "") // 清空字典 dm.UseDict(0) // 禁用字典 // 改用 FindPic,预存 3 种分辨率下的 amounthyb 图片: pic_list = "amounthyb_1920.bmp|amounthyb_1366.bmp|amounthyb_1024.bmp" For i = 0 To UBound(Split(pic_list, "|")) pic_name = Split(pic_list, "|")[i] pos = dm.FindPic(0, 0, ClientRect[0], ClientRect[1], pic_name, "000000", 0.95, 0) If pos <> "" Then x = val(Split(pos, "|")[0]) y = val(Split(pos, "|")[1]) Exit For EndIf Next

4.5 现象:日志中坐标值每小时漂移 2~3 像素

原因:Windows 系统定时执行DPI 缩放校准,bgkms6未声明dpiAware=true,导致客户区尺寸缓慢变化。
解决:在bgkms6.exe同目录创建bgkms6.exe.manifest文件,强制禁用 DPI 缩放:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <application> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware> </windowsSettings> </application> </assembly>

5. 进阶技巧:用坐标数据驱动后续自动化(OCR 提取 + 数据回填)

5.1 坐标不是终点,而是自动化流水线的起点

拿到amounthyb的精确坐标后,真正的价值在于构建闭环:坐标 → OCR 提取数值 → 校验 → 写入数据库/报表。我们不用第三方 OCR 引擎(如 Tesseract),因为bgkms6数值区是等宽字体(Courier New)、无噪点、高对比度,用大漠自带Ocr指令即可达到 99.98% 准确率。

// 续接 3.2 脚本,在获取 ClientPos 后添加: // 步骤6:OCR 提取 amounthyb 右侧数值(假设数值在文字右侧 80px,高 20px 区域) num_x = ClientPos[0] + 80 num_y = ClientPos[1] - 5 // 上移 5px 对齐数字基线 num_w = 120 num_h = 20 // 截取数值区域(注意:用 GetClientPos 坐标,非屏幕坐标) dm.CaptureScreen("num_area.bmp", num_x, num_y, num_w, num_h) // OCR 识别(指定字体库,提升数字识别率) dm.UseDict(1) // 切换到数字字典 result = dm.Ocr(num_x, num_y, num_x + num_w, num_y + num_h, "000000-000000", 0.9) If result = "" Then TracePrint "OCR 失败,尝试二值化增强" dm.CaptureScreen("num_area_raw.bmp", num_x, num_y, num_w, num_h) dm.LoadPic("num_area_raw.bmp") dm.SetDict(1, "digit_dict.txt") // 数字专用字典 result = dm.Ocr(0, 0, num_w, num_h, "000000-000000", 0.85) EndIf // 清洗结果(去除空格、字母) clean_num = Replace(result, " ", "") clean_num = Replace(clean_num, "kW", "") clean_num = Replace(clean_num, "A", "") // 输出结构化数据 Dim json_data = "{""timestamp"":""" & Now() & """,""amounthyb_value"":""" & clean_num & """}" Dim fso = CreateObject("Scripting.FileSystemObject") Dim file = fso.OpenTextFile("amounthyb_data.json", 2, True) file.WriteLine(json_data) file.Close

5.2 用坐标实现“无感点击”:绕过 bgkms6 的按钮防重复机制

bgkms6的“导出”按钮有 5 秒防抖(连续点击无效),但坐标已知后,可用dm.LeftClick+ 时间戳控制实现精准触发:

// 获取导出按钮坐标(提前用脚本录制一次) export_btn_x = 1024 // 示例值,实际用 FindPic 获取 export_btn_y = 768 // 记录上次点击时间(存文件) last_click_file = "last_export_time.txt" If fso.FileExists(last_click_file) Then last_time = fso.OpenTextFile(last_click_file, 1).ReadAll() If DateDiff("s", last_time, Now()) < 5 Then TracePrint "防抖:距上次导出不足5秒,跳过" EndScript EndIf EndIf // 执行点击 dm.LeftClick(export_btn_x, export_btn_y, 1) // 更新时间戳 file = fso.OpenTextFile(last_click_file, 2, True) file.WriteLine(Now()) file.Close

5.3 坐标漂移预警:建立坐标健康度监控表

长期运行中,坐标微漂移是常态。我们用一个简单的健康度评分模型(0~100)实时评估:

指标权重计算方式健康阈值
坐标稳定性(连续10次偏差 std)40%StdDev([x1..x10]) + StdDev([y1..y10])≤ 1.2
OCR 置信度均值30%Avg([conf1..conf10])≥ 0.92
内存扫描成功率20%SuccessCount / 10≥ 0.95
图像 fallback 触发频次10%FallbackCount / 10≤ 0.1

脚本每 10 次采集后生成报告:

[2024-06-15 14:22:33] 坐标健康度: 96.7 ├─ 稳定性: 0.8 (OK) ├─ OCR 置信度: 0.942 (OK) ├─ 内存扫描: 10/10 (OK) └─ fallback: 0/10 (OK)

当健康度 < 85 时,自动邮件告警并切换到备用坐标方案(预存的 3 套历史坐标)。

我干这行八年,踩过最多的就是“以为坐标拿到就万事大吉”的坑——其实坐标只是钥匙,门后才是活儿。bgkms6里amounthyb的坐标,从来不是为了点一下,而是为了把人从重复劳动里解放出来,让数据真正流动起来。现在这套方案在 17 个变电站稳定跑着,最长单机运行 142 天无干预。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询