Windows下自动化脚本工具AutoHotkey

前言

AutoHotkey

AutoHotkey(简称 AHK)是一款免费、开源的 Windows 自动化脚本语言,主要用于创建热键(快捷键)、热字符串(自动替换文本)、自动化任务以及 GUI(图形用户界面)应用程序。

语法

热键

1
2
3
4
5
; 按 Ctrl + J 发送 "Hello"
^j::Send, Hello

; Win + Alt + S 打开记事本
#!s::Run, notepad.exe

辅助键

  • # = Win 键
  • ! = Alt
  • ^ = Ctrl
  • + = Shift

ToolTip

显示提示

1
ToolTip, 开始执行, , , 2

清除提示

1
ToolTip  ; 清除提示

延迟

1
Sleep, 800

代码块

代码块有两种方式

  • 标签
  • 函数

标签

子程序中可以直接修改全局变量。

基本示例

1
2
3
4
; 技能 1
CastSkill1:
Send {1}
return

单次调用

子程序调用

1
Gosub, CastSkill1

循环调用

1
SetTimer, CastSkill1, 5000

停止

1
SetTimer, CastSkill1, Off

函数

函数默认都是局部变量,要修改全局变量要添加global关键字。

基本示例

定义及调用

1
2
3
4
5
6
7
8
9
counter := 0

Increment() {
global counter ; 声明使用全局变量
counter += 1
}

Increment()
MsgBox, %counter% ; 显示 1

局部变量与全局变量

1
2
3
4
5
6
7
8
9
10
11
; 推荐格式
MyFunction(param1, ByRef output) {
local localVar := "临时变量"
global globalVar

; 逻辑处理
result := param1 * 2
output := result + 10

return result
}

循环调用

SetTimer 只能调用标签,调用函数会报错。

判断窗口是否激活

窗口没有激活判断

1
2
3
4
5
IfWinNotActive, ahk_class Diablo IV Main Window Class
{
v_Enable := 0
Gosub, StopCombatLoop
}

注意

{一定要换行,否则会报错。

按键监听

监听并屏蔽原功能

1
2
3
$F2::

return

注意

$F2::F2::的主要区别在于 是否防止热键触发自身的递归(即“避免自我触发”)

比如

危险

1
F2::Send, {F2}  ; 按下 F2 后发送 F2 → 再次触发 F2 → 无限循环!

安全

1
$F2::Send, {F2}  ; 按下 F2 后发送 F2,但不会再次触发此热键

只监听不屏蔽原功能

AutoHotkey v1 中,~Tab:: 的含义是:

监听 Tab 键的按下事件,但不阻止系统/应用程序接收到这个按键。

多个按键监听

1
2
3
4
5
6
7
8
9
10
11
12
13
~B::
~C::
~Tab::
if (!v_Enable)
return ; 宏未启用,忽略按键
v_Tab := !v_Tab ; 切换暂停状态

if (v_Tab) {
Gosub, StopCombatLoop
} else {
Gosub, StartCombatLoop
}
return

进阶

AutoHotkey v1 中,~*LButton:: 是一个热键定义,其中包含了两个特殊前缀符号:~*

示例

1
2
3
~*LButton::
; 你的代码
return

综合含义

无论是否按住 Ctrl/Alt/Shift/Win,只要点击鼠标左键,就执行这段代码,同时保留左键的原始功能(如点击、拖拽、选择等)。

含义

它们的组合具有特定含义:

LButton

  • 表示 鼠标左键(Left Mouse Button)。
  • 是 AHK 中代表鼠标按键的标准名称。

~(波浪号)

  • 含义:透传(Pass-through)

  • 效果:不屏蔽原始鼠标点击行为

    即:你的脚本会执行自定义动作,同时系统和应用程序仍会正常收到“左键按下”事件。

*(星号)

  • 含义:无视修饰键(Ignore modifier keys)

  • 效果:无论是否按着热键就会触发。

    • 普通写法 LButton:: 只在 没有任何修饰键按下时 才触发。
    • 加了 * 后,Ctrl+LButtonShift+LButton 等也会触发同一个热键。

对比示例

写法 触发条件 是否屏蔽左键原始功能
LButton:: 仅纯左键点击 ❌ 屏蔽
~LButton:: 仅纯左键点击 ✅ 不屏蔽
*LButton:: 任意组合(如 Ctrl+左键) ❌ 屏蔽
~*LButton:: 任意组合 ✅ 不屏蔽

点击事件

单击1

1
Send {1}

鼠标左键

1
Click

鼠标右键

1
Click Right

按键按下与抬起

1
2
Send {a down}
Send {a up}

定时任务

开启定时任务

1
SetTimer, CastSkill1, 5000

关闭定时任务

1
SetTimer, CastSkill1, Off

脚本示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
; ===================================================================
; 自动战斗宏脚本(适用于 AHK v1)
; 功能:自动释放技能、左右横移、自动攻击,并支持暂停/恢复
; 适用窗口:ahk_class Diablo IV Main Window Class
; ===================================================================

#IfWinActive, ahk_class Diablo IV Main Window Class

; === 配置区(可根据角色/技能调整)===
SetKeyDelay, 20 ; 按键发送延迟(毫秒)
SetMouseDelay, 20 ; 鼠标点击延迟(毫秒)

; === 全局状态变量 ===
vEnable := 0 ; 宏总开关:0=关闭,1=开启
vWinActive := 0 ; 是否游戏主页面激活
direction := 0 ; 横移方向:0=向右(按 d),1=向左(按 a)

; -------------------------------------------------------------------
; F2:启用
; -------------------------------------------------------------------
$F2::
if (vEnable)
return ; 已经启用,忽略按键
vEnable := 1 ; 切换宏启用状态
Gosub, EnsureGameIsActive ; 先检查游戏窗口是否激活
if (vEnable) {
Gosub, StartCombatLoop ; 启动所有自动行为
}
return

; -------------------------------------------------------------------
; F3:停止
; -------------------------------------------------------------------
$F3::
vEnable := 0
Gosub, StopCombatLoop ; 停止所有定时器并释放按键
return

; -------------------------------------------------------------------
; 暂停/恢复快捷键
; 仅在宏已启用时生效,用于临时中断循环(如拾取物品、对话)
; -------------------------------------------------------------------

~*Tab::
~A::
~C::
vEnable := 0
Gosub, StopCombatLoop ; 停止所有定时器并释放按键
return

; -------------------------------------------------------------------
; 技能与操作子程序(每个对应一个游戏内动作)
; -------------------------------------------------------------------

; 技能 1
CastSkill1:
if(vEnable && vWinActive){
Send {1}
}

return

; 技能 4
CastSkill4:
if(vEnable && vWinActive){
Send {4}
}
return

; 自动左键攻击(主攻,高频触发)
CastSkillLeft:
if(vEnable && vWinActive){
Send {Shift down}
Click
Send {Shift up}
}
Gosub, EnsureGameIsActive ; 每次点击后检查窗口是否仍激活
return

; 右键技能(通常为闪避、互动或次要技能)
CastSkillRight:
if(vEnable && vWinActive){
Click Right
}
return

; -------------------------------------------------------------------
; 子程序:左右横移
; -------------------------------------------------------------------
ActionMove:
if (vEnable && vWinActive) {
if (direction = 0) {
; 当前向右 → 切换为向左
Send {a down}
Send {d up}
direction := 1
} else {
; 当前向左 → 切换为向右
Send {a up}
Send {d down}
direction := 0
}
}
return

; -------------------------------------------------------------------
; 子程序:启动所有自动战斗行为(设置定时器)
; -------------------------------------------------------------------
StartCombatLoop:
SetTimer, CastSkill1, 5000
SetTimer, CastSkill4, 5000
SetTimer, CastSkillLeft, 500
SetTimer, CastSkillRight, 5000
return

; -------------------------------------------------------------------
; 子程序:停止所有自动行为(关闭定时器 + 释放按键)
; -------------------------------------------------------------------
StopCombatLoop:
SetTimer, CastSkill1, Off
SetTimer, CastSkill4, Off
SetTimer, CastSkillLeft, Off
SetTimer, CastSkillRight, Off
; 显式释放移动键,防止角色卡住
Send {a up}
Send {d up}
return

; -------------------------------------------------------------------
; 子程序:确保当前激活窗口是 Diablo IV
; 若不是,则暂停宏,防止误操作其他程序
; -------------------------------------------------------------------
EnsureGameIsActive:
IfWinActive, ahk_class Diablo IV Main Window Class
{
vWinActive := 1
}else{
vWinActive := 0
}
return

; 结束条件编译指令
#IfWinActive