AutoHotkey v2电池悬浮GUI脚本无故自动退出问题求助
问题原因分析
你的脚本GUI随机消失的核心原因有两个:
- DllCall内存越界:调用
GetSystemPowerStatus时,你只创建了3字节的Buffer,但该API需要写入完整的SYSTEM_POWER_STATUS结构体(共12字节),内存越界会破坏脚本运行时的内存区域,导致GUI对象被意外销毁或脚本崩溃。 - 函数作用域问题:AutoHotkey v2默认函数为局部作用域,
update函数中未声明battery为全局变量,虽然当前代码可能暂时能运行,但存在访问异常的潜在风险,可能触发不可预期的错误。
另外,+ToolWindow样式的窗口可能被系统窗口管理机制或第三方软件(如任务栏工具、杀毒软件)误判为临时窗口而关闭,这也是GUI随机消失的诱因之一。
修复后的代码
#SingleInstance Force Persistent ; 确保脚本保持运行 ; 创建GUI,去掉ToolWindow样式,替换分层窗口样式增强稳定性 battery := Gui("+AlwaysOnTop -Caption -Disabled +E0x20 +E0x80000 -DPIScale", "BatteryOverlay") battery.BackColor := "100100" WinSetTransColor "100100 130", battery.Hwnd ; 添加进度条控件 battery.Add("Progress", "x0 y0 w28 h18 background000000", 0) battery.Add("Progress", "x0 y6 w30 h8 background000000", 0) battery.Add("Progress", "x1 y1 w26 h16 backgroundFFFFFF", 0) battery.Add("Progress", "x1 y7 w28 h6 backgroundFFFFFF", 0) battery.Add("Progress", "x3 y3 w22 h12 background000000", 0) battery.Add("Progress", "x4 y4 w20 h10 cFFFFFF background000000 vprogress", 0) update() { global battery ; 声明访问全局GUI对象 ; 创建足够大小的Buffer存储SYSTEM_POWER_STATUS结构体(12字节) status := Buffer(12) DllCall("GetSystemPowerStatus", "Ptr", status) batteryPercent := NumGet(status, 2, "UChar") ; 获取电池百分比 ; 更新进度条状态与颜色 battery["progress"].Value := batteryPercent battery["progress"].Opt("c" (batteryPercent < 20 ? "FF5555" : "FFFFFF")) ; 保持窗口位置适配屏幕尺寸变化 battery.Show("x" (A_ScreenWidth - 34) " y" (A_ScreenHeight - 22) " NoActivate") } ; 初始更新并启动定时器 update() SetTimer update, 60000 ; 退出时正确销毁GUI资源 OnExit(*) => battery.Destroy()
关键修复点说明
- 修复内存越界:将
Buffer(3)改为Buffer(12),匹配API所需结构体的实际大小,彻底避免内存破坏导致的随机错误。 - 明确作用域:在
update函数中添加global battery,确保函数能稳定访问全局GUI对象。 - 调整窗口样式:移除
+ToolWindow,添加+E0x80000(WS_EX_LAYERED)分层窗口样式,增强透明悬浮窗的系统兼容性,减少被误关的概率。 - 完善生命周期管理:添加
Persistent确保脚本后台运行,通过OnExit回调在退出时清理GUI资源,避免残留问题。
内容的提问来源于stack exchange,提问作者TGekko
相关产品推荐
相关产品推荐

