├── base.ahk
├── scripts
├── win.ahk
├── myHotString.ahk
├── capslock.ahk
└── switchIME.ahk
├── .promptx
├── memory
│ └── declarative.md
└── resource
│ ├── domain
│ └── autohotkey-expert
│ │ ├── autohotkey-expert.role.md
│ │ ├── thought
│ │ └── autohotkey-mindset.thought.md
│ │ └── execution
│ │ └── autohotkey-workflow.execution.md
│ └── project.registry.json
├── LICENSE
├── .markdownlint.json
├── .trae
└── rules
│ └── project_rules.md
├── README.md
├── .gitignore
├── install-autohotkey.ps1
└── makeScripts.ps1
/base.ahk:
--------------------------------------------------------------------------------
1 | ; 拼接所有的ahk脚本的头部,做一些通用的设置
2 | #SingleInstance Force ;跳过对话框,执行此脚本时默认覆盖原来的同名脚本,只允许当前脚本的一个实例存在
3 | #Warn ;启用所有警告,并且把他们显示到消息框中
4 | SendMode "Input" ; 让 Send 成为 SendInput 的代名词. 由于其卓越的速度和可靠性, 推荐在新脚本中使用.
5 | SetWorkingDir A_ScriptDir ;设置脚本工作目录为当前脚本所在的目录。
6 |
--------------------------------------------------------------------------------
/scripts/win.ahk:
--------------------------------------------------------------------------------
1 |
2 |
3 | ; 批量关闭程序的函数,传入进程名或者pid数字
4 | processArrClose(processArr){
5 | For processName in processArr
6 | if (PID := ProcessExist(processName)){
7 | ProcessClose(PID)
8 | }
9 | }
10 |
11 | ; 下班时,按win+l 批量关闭程序
12 | #l::{
13 | ; 下班应该关闭的程序
14 | offDuttiesCloseProcessArr:= ["foobar2000.exe","QQMusic.exe"]
15 | processArrClose(offDuttiesCloseProcessArr)
16 | }
17 |
--------------------------------------------------------------------------------
/.promptx/memory/declarative.md:
--------------------------------------------------------------------------------
1 | # 陈述性记忆
2 |
3 | ## 高价值记忆(评分 ≥ 7)
4 |
5 | - 2025/07/05 00:56 START
6 | 成功创建AutoHotkey专家角色的完整流程和经验:
7 |
8 | 1. 角色创建过程:
9 | - 使用女娲角色的专业能力
10 | - 创建了完整的DPML角色文件结构
11 | - 包含personality、principle、knowledge三个核心组件
12 | - 使用@!引用机制链接思维和执行文件
13 |
14 | 2. 文件结构:
15 | - 主角色文件:autohotkey-expert.role.md
16 | - 思维文件:thought/autohotkey-mindset.thought.md
17 | - 执行文件:execution/autohotkey-workflow.execution.md
18 | - 位置:.promptx/resource/domain/autohotkey-expert/
19 |
20 | 3. 角色特色:
21 | - 专注于AutoHotkey脚本开发和自动化
22 | - 包含完整的开发工作流程
23 | - 具备专业的调试和优化思维
24 | - 提供标准化的代码模板和最佳实践
25 |
26 | 4. 验证结果:
27 | - 角色成功激活并正常工作
28 | - 系统正确识别和加载所有组件
29 | - 具备完整的专业能力和知识体系
30 |
31 | 这次创建展示了女娲角色的强大能力,能够快速生成高质量的专业AI角色。 --tags 女娲 角色创建 AutoHotkey 成功案例 DPML
32 | --tags #最佳实践 #流程管理 #评分:8 #有效期:长期
33 | - END
34 |
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 mudssky
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "default": true,
3 | // MD004 统一无序列表的格式,最内层使用- ,顺序依次为- + *
4 | "ul-style": true,
5 | // MD009 尾部空格只能是0或2个,两个表示换行
6 | "no-trailing-spaces": true,
7 |
8 | // MD010 空格代替tab
9 | "no-hard-tabs": true,
10 | // 禁止多个连续空行
11 | "no-multiple-blanks": true,
12 | // 行宽限制,默认是80
13 | "line-length": false,
14 | // 标题# 后面应该只有一个空格
15 | "no-multiple-space-atx": true,
16 | // 标题需要被空行包围
17 | "blanks-around-headers": true,
18 | // MD024/no-duplicate-heading,只检查相同父节点的
19 | "no-duplicate-heading": {
20 | "allow_different_nesting": true
21 | // "siblings_only": true
22 | },
23 | // 有序列表需要按照顺序
24 | "ol-prefix": true,
25 | // 隔离的代码块需要被空行包围
26 | "blanks-around-fences": true,
27 | // MD033/no-inline-html,html还是有用的,所以关掉这个
28 | "no-inline-html": false,
29 | // MD81 不能用强调符号作为标题,这是为了语义,但是太烦了,还是关掉
30 | "no-emphasis-as-heading": false,
31 | // 第一行需要是最高级别标题
32 | "first-line-heading": false,
33 | // 文件需要以一个新的换行符结尾
34 | // Files should end with a single newline character
35 | "single-trailing-newline": true,
36 | // 代码块需要指定语言,如果不需要高亮,可以指定为text,过于繁琐,所以关掉
37 | "fenced-code-language": false
38 | }
39 |
--------------------------------------------------------------------------------
/.promptx/resource/domain/autohotkey-expert/autohotkey-expert.role.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | @!thought://autohotkey-mindset
4 | @!thought://remember
5 | @!thought://recall
6 |
7 |
8 |
9 | @!execution://autohotkey-workflow
10 |
11 |
12 |
13 | # AutoHotkey专业知识体系
14 |
15 | ## 核心语法掌握
16 | - **变量与数据类型**:字符串、数字、对象、数组的使用
17 | - **控制结构**:If/Else、Loop、While、For循环
18 | - **函数定义**:自定义函数、参数传递、返回值
19 | - **热键与热字符串**:快捷键绑定、文本替换
20 |
21 | ## 系统交互能力
22 | - **窗口操作**:WinActivate、WinClose、WinMove等
23 | - **鼠标控制**:Click、MouseMove、MouseGetPos
24 | - **键盘模拟**:Send、SendRaw、SendInput
25 | - **文件操作**:FileRead、FileAppend、FileDelete
26 |
27 | ## 高级功能应用
28 | - **GUI界面设计**:创建用户界面、控件事件处理
29 | - **正则表达式**:文本匹配和替换
30 | - **COM对象**:与其他应用程序交互
31 | - **DLL调用**:调用Windows API
32 |
33 | ## 实用脚本模式
34 | - **自动化办公**:文档处理、数据录入
35 | - **游戏辅助**:按键宏、自动操作
36 | - **系统优化**:快捷操作、效率提升
37 | - **文本处理**:批量替换、格式转换
38 |
39 | ## 调试与优化
40 | - **错误处理**:Try/Catch异常捕获
41 | - **性能优化**:减少资源占用、提高执行效率
42 | - **代码规范**:命名约定、注释标准
43 | - **版本兼容**:AHK v1与v2的差异处理
44 |
45 |
--------------------------------------------------------------------------------
/scripts/myHotString.ahk:
--------------------------------------------------------------------------------
1 | ; 获取当前的时间戳精确到秒
2 | GetCurrentTimeStamp(){
3 | ; unix时间戳的起始时间精确到秒
4 | startTime :='19700101000000'
5 | ; datediff 计算现在的utc时间到unix时间戳的起始时间经过的秒数
6 | return DateDiff(A_NowUTC,startTime,'Seconds')
7 | }
8 | ; 设置终止符 空格,回车和tab
9 | Hotstring("EndChars", "`n `t")
10 | ; 替换日期和时间
11 | ::rq:: {
12 | ; send FormatTime("R")
13 | send FormatTime(,"yyyy年M月d日 dddd HH:mm:ss")
14 | }
15 | ; 日期 YYYYMMDDHH24MISS 格式,也就是19700101000000,这种全是数字的日期
16 | ::rqss:: {
17 | send A_Now
18 | }
19 | ; 输出当前时间戳(秒)热词
20 | ::sjc:: {
21 | send GetCurrentTimeStamp()
22 | }
23 | ; 热字符串由终止符触发,包含下面几个
24 | ; -()[]{}':;"/\,.?!`n `t
25 | ; 其中`n是回车 Enter
26 | ; `t 是Tab
27 | ; 上面`t前面其实还有一个空格,空格也是终止符
28 |
29 | ; TimeString := FormatTime()
30 | ; MsgBox "The current time and date (time first) is " TimeString
31 |
32 | ; TimeString := FormatTime("R")
33 | ; MsgBox "The current time and date (date first) is " TimeString
34 |
35 | ; TimeString := FormatTime(, "Time")
36 | ; MsgBox "The current time is " TimeString
37 |
38 | ; TimeString := FormatTime("T12", "Time")
39 | ; MsgBox "The current 24-hour time is " TimeString
40 |
41 | ; TimeString := FormatTime(, "LongDate")
42 | ; MsgBox "The current date (long format) is " TimeString
43 |
44 | ; TimeString := FormatTime(20050423220133, "dddd MMMM d, yyyy hh:mm:ss tt")
45 | ; MsgBox "The specified date and time, when formatted, is " TimeString
46 |
47 | ; MsgBox FormatTime(200504, "'Month Name': MMMM`n'Day Name': dddd")
48 |
49 | ; YearWeek := FormatTime(20050101, "YWeek")
50 | ; MsgBox "January 1st of 2005 is in the following ISO year and week number: " YearWeek
--------------------------------------------------------------------------------
/.trae/rules/project_rules.md:
--------------------------------------------------------------------------------
1 | # AutoHotkey 项目规则
2 |
3 | ## 代码风格规范
4 |
5 | ### 命名规范
6 |
7 | - 变量名使用驼峰命名法(camelCase)
8 | - 函数名使用帕斯卡命名法(PascalCase)
9 | - 常量使用全大写加下划线(UPPER_SNAKE_CASE)
10 | - 热键标签使用描述性名称,避免使用数字开头
11 |
12 | ### 代码格式
13 |
14 | - 使用4个空格进行缩进,不使用制表符
15 | - 每行代码长度不超过100个字符
16 | - 在操作符前后添加空格
17 | - 函数参数之间用逗号和空格分隔
18 | - 大括号采用Allman风格(独占一行)
19 |
20 | ### 注释规范
21 |
22 | - 每个脚本文件开头必须包含文件说明注释
23 | - 复杂逻辑必须添加行内注释
24 | - 热键功能必须添加功能说明注释
25 | - 使用中文注释,保持简洁明了
26 |
27 | ## AutoHotkey 特定规范
28 |
29 | ### 热键定义
30 |
31 | - 优先使用组合键而非单键热键
32 | - 热键定义后必须添加return语句
33 | - 避免与系统热键冲突
34 | - 热键功能要有明确的用途说明
35 |
36 | ### 脚本结构
37 |
38 | - 将相关功能的热键组织在一起
39 | - 使用分隔注释区分不同功能模块
40 | - 公共函数放在文件末尾
41 | - 避免在热键中编写过长的代码逻辑
42 |
43 | ### 错误处理
44 |
45 | - 对可能失败的操作添加错误检查
46 | - 使用Try-Catch处理异常情况
47 | - 提供用户友好的错误提示
48 | - 记录关键操作的执行状态
49 |
50 | ## 开发约束
51 |
52 | ### 安全性
53 |
54 | - 不允许执行可能损害系统的操作
55 | - 避免自动删除重要文件
56 | - 对敏感操作添加确认机制
57 | - 不在脚本中硬编码敏感信息
58 |
59 | ### 性能要求
60 |
61 | - 避免在热键中使用耗时操作
62 | - 合理使用Sleep语句控制执行速度
63 | - 及时释放不再使用的资源
64 | - 避免创建无限循环
65 |
66 | ### 兼容性
67 |
68 | - 优先使用AutoHotkey v2语法
69 | - 确保脚本在Windows 10/11上正常运行
70 | - 考虑不同分辨率和DPI设置的兼容性
71 | - 测试多显示器环境下的表现
72 |
73 | ## 文档要求
74 |
75 | ### README文档
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 | ### Git规范
108 |
109 | - 提交信息使用中文,格式:[类型] 简要描述
110 | - 类型包括:新增、修复、优化、重构、文档
111 | - 避免提交临时文件和调试代码
112 | - 定期整理和清理无用代码
113 |
114 | ### 发布管理
115 |
116 | - 重要功能更新要创建新的版本标签
117 | - 维护CHANGELOG记录变更历史
118 | - 确保发布版本经过充分测试
119 | - 提供版本升级指导
120 |
--------------------------------------------------------------------------------
/.promptx/resource/domain/autohotkey-expert/thought/autohotkey-mindset.thought.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## AutoHotkey专家思维特征
4 |
5 | ### 自动化思维模式
6 | - **效率导向**:始终思考如何通过脚本提高工作效率
7 | - **模式识别**:善于发现重复性操作并将其自动化
8 | - **系统思维**:理解Windows系统机制,知道如何与之交互
9 | - **用户体验**:关注脚本的易用性和稳定性
10 |
11 | ### 问题解决策略
12 | - **分解思维**:将复杂任务分解为简单的步骤
13 | - **测试驱动**:先写简单版本,再逐步完善
14 | - **兼容性考虑**:考虑不同系统环境和AHK版本
15 | - **错误预防**:预见可能的问题并提前处理
16 |
17 | ### 代码设计理念
18 | - **简洁明了**:代码易读易懂,注释清晰
19 | - **模块化**:功能分离,便于维护和复用
20 | - **健壮性**:处理异常情况,避免脚本崩溃
21 | - **可配置性**:通过变量或配置文件调整行为
22 |
23 |
24 |
25 | ## AutoHotkey专业推理逻辑
26 |
27 | ### 需求分析流程
28 | 1. **理解用户意图**:明确要解决的具体问题
29 | 2. **评估可行性**:判断AutoHotkey是否适合解决该问题
30 | 3. **设计方案**:选择最合适的实现方式
31 | 4. **考虑边界**:处理异常情况和边界条件
32 |
33 | ### 技术选择原则
34 | - **原生优先**:优先使用AutoHotkey内置功能
35 | - **性能考虑**:选择执行效率高的方法
36 | - **兼容性**:确保在目标环境中正常运行
37 | - **维护性**:代码结构清晰,便于后续修改
38 |
39 | ### 调试思维模式
40 | - **逐步验证**:分段测试,定位问题所在
41 | - **日志记录**:输出关键信息帮助调试
42 | - **环境检查**:确认系统环境和权限设置
43 | - **版本适配**:检查AHK版本兼容性问题
44 |
45 |
46 |
47 | ## 常见挑战与应对
48 |
49 | ### 技术挑战
50 | - **窗口识别问题**:使用多种方法确保准确识别目标窗口
51 | - **时序控制**:合理设置延时,确保操作的可靠性
52 | - **权限限制**:处理UAC和管理员权限问题
53 | - **编码问题**:正确处理中文和特殊字符
54 |
55 | ### 用户体验挑战
56 | - **操作冲突**:避免脚本与用户操作产生冲突
57 | - **资源占用**:优化脚本性能,减少系统负担
58 | - **错误提示**:提供友好的错误信息和解决建议
59 | - **配置复杂**:简化配置过程,提供默认设置
60 |
61 |
62 |
63 | ## AutoHotkey专家工作计划
64 |
65 | ### 脚本开发流程
66 | 1. **需求确认**:与用户确认具体需求和期望效果
67 | 2. **方案设计**:设计实现方案和代码结构
68 | 3. **核心实现**:编写核心功能代码
69 | 4. **测试验证**:在实际环境中测试脚本
70 | 5. **优化完善**:根据测试结果优化代码
71 | 6. **文档说明**:提供使用说明和注意事项
72 |
73 | ### 持续改进策略
74 | - **收集反馈**:了解用户使用体验和问题
75 | - **版本更新**:跟进AutoHotkey新版本特性
76 | - **最佳实践**:总结和分享优秀的解决方案
77 | - **社区参与**:参与AutoHotkey社区讨论和学习
78 |
79 |
--------------------------------------------------------------------------------
/.promptx/resource/project.registry.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "source": "project",
4 | "metadata": {
5 | "version": "2.0.0",
6 | "description": "project 级资源注册表",
7 | "createdAt": "2025-07-04T16:55:44.268Z",
8 | "updatedAt": "2025-07-04T16:55:44.269Z",
9 | "resourceCount": 3
10 | },
11 | "resources": [
12 | {
13 | "id": "autohotkey-expert",
14 | "source": "project",
15 | "protocol": "role",
16 | "name": "Autohotkey Expert 角色",
17 | "description": "专业角色,提供特定领域的专业能力",
18 | "reference": "@project://.promptx/resource/domain/autohotkey-expert/autohotkey-expert.role.md",
19 | "metadata": {
20 | "createdAt": "2025-07-04T16:55:44.269Z",
21 | "updatedAt": "2025-07-04T16:55:44.269Z",
22 | "scannedAt": "2025-07-04T16:55:44.269Z"
23 | }
24 | },
25 | {
26 | "id": "autohotkey-mindset",
27 | "source": "project",
28 | "protocol": "thought",
29 | "name": "Autohotkey Mindset 思维模式",
30 | "description": "思维模式,指导AI的思考方式",
31 | "reference": "@project://.promptx/resource/domain/autohotkey-expert/thought/autohotkey-mindset.thought.md",
32 | "metadata": {
33 | "createdAt": "2025-07-04T16:55:44.269Z",
34 | "updatedAt": "2025-07-04T16:55:44.269Z",
35 | "scannedAt": "2025-07-04T16:55:44.269Z"
36 | }
37 | },
38 | {
39 | "id": "autohotkey-workflow",
40 | "source": "project",
41 | "protocol": "execution",
42 | "name": "Autohotkey Workflow 执行模式",
43 | "description": "执行模式,定义具体的行为模式",
44 | "reference": "@project://.promptx/resource/domain/autohotkey-expert/execution/autohotkey-workflow.execution.md",
45 | "metadata": {
46 | "createdAt": "2025-07-04T16:55:44.269Z",
47 | "updatedAt": "2025-07-04T16:55:44.269Z",
48 | "scannedAt": "2025-07-04T16:55:44.269Z"
49 | }
50 | }
51 | ],
52 | "stats": {
53 | "totalResources": 3,
54 | "byProtocol": {
55 | "role": 1,
56 | "thought": 1,
57 | "execution": 1
58 | },
59 | "bySource": {
60 | "project": 3
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | - [myAHKScripts](#myahkscripts)
3 | - [安装](#安装)
4 | - [01. capslock.ahk](#01-capslockahk)
5 | - [02.switchIME.ahk](#02switchimeahk)
6 | - [03.win.ahk](#03winahk)
7 | - [04.鼠标连点器](#04鼠标连点器)
8 |
9 | # myAHKScripts
10 |
11 | 存放自己编写的autohotkey脚本,全部基于v2版本的语法。
12 | 脚本统一存放在scripts目录
13 |
14 | ## 安装
15 |
16 | ### 1. 安装 AutoHotkey 2.0
17 |
18 | 项目提供了自动安装脚本 `install-autohotkey.ps1`,可以自动下载并安装最新版本的 AutoHotkey 2.0:
19 |
20 | ```powershell
21 | # 以管理员身份运行 PowerShell,然后执行:
22 | .\install-autohotkey.ps1
23 |
24 | # 静默安装(无用户交互)
25 | .\install-autohotkey.ps1 -Silent
26 |
27 | # 强制重新安装(即使已安装)
28 | .\install-autohotkey.ps1 -Force
29 | ```
30 |
31 | **注意事项:**
32 | - 建议以管理员身份运行 PowerShell
33 | - 确保 PowerShell 执行策略允许运行脚本
34 | - 脚本会自动从 GitHub 下载最新版本
35 | - 安装完成后需要重启终端以使用 AutoHotkey 命令
36 |
37 | ### 2. 部署脚本
38 |
39 | makeScripts是powershell脚本,用于把scripts目录里面的所有脚本和base.ahk拼接成一个并且在startup目录创建快捷方式,然后再执行一遍最终生成的ahk脚本。
40 |
41 | 注意先确认powershell的执行权限,还有autohotkey v2是否正确安装再执行。
42 | **可能会需要管理员权限才能执行**。
43 |
44 | 默认会采用include的方式进行拼接,有一个 `-concatNotInclude`参数,如果传递给脚本
45 | 最后生成的ahk文件就是完整拼接的了。
46 |
47 | ## 01. capslock.ahk
48 |
49 | 定制capslock键作为修饰键
50 | 使用了官方提供的代码,完全禁用capslock键并且排除IME带来的干扰,使用capslock+esc代替capslock原来的功能。
51 |
52 | |快捷键|功能|
53 | |---|---|
54 | |Capslock+t|窗口置顶toggle|
55 | |Capslock+esc|大写锁定切换|
56 |
57 | ## 02.switchIME.ahk
58 |
59 | 提供自动切换输入法的功能。
60 |
61 | 需要把默认输入法调成微软拼音,进入特定的几个app比如vscode 或者windows terminal 就会用shift切换到英文模式,离开这些app的时候就会切换回中文模式。
62 |
63 | |快捷键|功能|
64 | |---|---|
65 | |Capslock+1|切换为微软拼音输入法|
66 | |Capslock+2|切换为微软英文键盘|
67 | |Capslock+3|切换为微软日文输入法|
68 |
69 | ## 03.win.ahk
70 |
71 | win相关的快捷键
72 | 定义`win+l`热键用于下班时,一键关闭一些应用程序
73 | 在数组中放入进程名即可
74 |
75 | ```ahk
76 | offDuttiesCloseProcessArr:= ["foobar2000.exe","QQMusic.exe"]
77 | ```
78 |
79 | ## 04.鼠标连点器
80 |
81 | | 快捷键 | 功能 |
82 | | ---------- | ------------------------------------------------------------ |
83 | | Capslock+c | 连续点击,超过10分钟或者鼠标位移大于50停止 |
84 | | Capslock+r | 停止点击,重置计数器,重置鼠标指针到屏幕中心(多屏幕的时候找不到鼠标指针时好用) |
85 | | CapsLock+m | 输入点击的时间间隔 |
86 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # 忽略azurlane文件夹
3 | azurlane/
4 |
5 | # 忽略包含个人信息的secrets.ahk文件
6 |
7 | # 忽略最终生成的总脚本文件
8 | ignore/
9 | secrets.ahk
10 | myAllScripts.ahk
11 | # Logs
12 | logs
13 | *.log
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 | lerna-debug.log*
18 |
19 | # Diagnostic reports (https://nodejs.org/api/report.html)
20 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
21 |
22 | # Runtime data
23 | pids
24 | *.pid
25 | *.seed
26 | *.pid.lock
27 |
28 | # Directory for instrumented libs generated by jscoverage/JSCover
29 | lib-cov
30 |
31 | # Coverage directory used by tools like istanbul
32 | coverage
33 | *.lcov
34 |
35 | # nyc test coverage
36 | .nyc_output
37 |
38 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
39 | .grunt
40 |
41 | # Bower dependency directory (https://bower.io/)
42 | bower_components
43 |
44 | # node-waf configuration
45 | .lock-wscript
46 |
47 | # Compiled binary addons (https://nodejs.org/api/addons.html)
48 | build/Release
49 |
50 | # Dependency directories
51 | node_modules/
52 | jspm_packages/
53 |
54 | # TypeScript v1 declaration files
55 | typings/
56 |
57 | # TypeScript cache
58 | *.tsbuildinfo
59 |
60 | # Optional npm cache directory
61 | .npm
62 |
63 | # Optional eslint cache
64 | .eslintcache
65 |
66 | # Microbundle cache
67 | .rpt2_cache/
68 | .rts2_cache_cjs/
69 | .rts2_cache_es/
70 | .rts2_cache_umd/
71 |
72 | # Optional REPL history
73 | .node_repl_history
74 |
75 | # Output of 'npm pack'
76 | *.tgz
77 |
78 | # Yarn Integrity file
79 | .yarn-integrity
80 |
81 | # dotenv environment variables file
82 | .env
83 | .env.test
84 |
85 | # parcel-bundler cache (https://parceljs.org/)
86 | .cache
87 |
88 | # Next.js build output
89 | .next
90 |
91 | # Nuxt.js build / generate output
92 | .nuxt
93 | dist
94 |
95 | # Gatsby files
96 | .cache/
97 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
98 | # https://nextjs.org/blog/next-9-1#public-directory-support
99 | # public
100 |
101 | # vuepress build output
102 | .vuepress/dist
103 |
104 | # Serverless directories
105 | .serverless/
106 |
107 | # FuseBox cache
108 | .fusebox/
109 |
110 | # DynamoDB Local files
111 | .dynamodb/
112 |
113 | # TernJS port file
114 | .tern-port
115 |
--------------------------------------------------------------------------------
/scripts/capslock.ahk:
--------------------------------------------------------------------------------
1 | ; 定制CapsLock
2 | ; 必须安装键盘钩子,官方提供的限制IME使得Capslock不会被触发可以正常映射的方法
3 | InstallKeybdHook
4 | SendSuppressedKeyUp(key) {
5 | DllCall("keybd_event"
6 | , "char", GetKeyVK(key)
7 | , "char", GetKeySC(key)
8 | , "uint", KEYEVENTF_KEYUP := 0x2
9 | , "uptr", KEY_BLOCK_THIS := 0xFFC3D450)
10 | }
11 | ; 设置大写锁定正常为一直关闭状态
12 | SetCapsLockState "AlwaysOff"
13 |
14 | ; 使用capslock+esc切换大写锁定
15 | ; 废除capslock直接切换大小写锁定的功能
16 | Capslock & Esc::{
17 | If GetKeyState("CapsLock", "T") = 1
18 | SetCapsLockState "AlwaysOff"
19 | Else
20 | SetCapsLockState "AlwaysOn"
21 | }
22 | ; toggle winAlwaysOnTop 实现窗口置顶 CapsLock+t
23 | CapsLock & t::{
24 | WinSetAlwaysOnTop -1, "A"
25 | }
26 |
27 | ; 切换窗口到 1280*720
28 | CapsLock & w::{
29 | ; 输入框宽和高
30 | wnhn := "W200 H100"
31 | title := WinGetTitle("A")
32 | widthInput := InputBox("输入调整的宽度(像素)", "输入宽度" ,wnhn).value
33 | heightInput := InputBox("输入调整的高度(像素)", "输入高度" ,wnhn).value
34 | if ( widthInput && heightInput){
35 | WinMove , ,widthInput,heightInput, title
36 | }else {
37 | MsgBox "宽度或高度未设置"
38 | }
39 | }
40 |
41 | ; 计算两点之间的距离
42 | calcDistance(x1,y1,x2,y2){
43 | return ((x2-x1)**2 + (y2-y1)**2)**0.5
44 | }
45 |
46 | ; 实现鼠标连点相关功能,启动连点后,鼠标出现位移则取消连点
47 | isMouseClickOn:=false
48 | mouseClickCount:=0
49 | clickInterval:=50
50 | CapsLock & c::{
51 | global isMouseClickOn,mouseClickCount,clickInterval
52 | isMouseClickOn :=true
53 | MouseGetPos &xpos, &ypos
54 | Loop{
55 | if isMouseClickOn{
56 | MouseClick("left")
57 | mouseClickCount++
58 | MouseGetPos &xpos2, &ypos2
59 | ; 连点超过十分钟自动停止
60 | if (mouseClickCount*clickInterval>1000*60*10){
61 | isMouseClickOn:=false
62 | break
63 | }
64 | if(calcDistance(xpos,ypos,xpos2,ypos2)>50){
65 | isMouseClickOn:=false
66 | break
67 | }
68 | }else{
69 | break
70 | }
71 | Sleep(clickInterval)
72 | }
73 | mouseClickCount:=0
74 | }
75 |
76 | resetMouseClick(){
77 | global isMouseClickOn,mouseClickCount
78 | isMouseClickOn:=false
79 | mouseClickCount:=0
80 | resetMousePosition()
81 | }
82 | ; 重置鼠标位置到屏幕中心,用于多屏幕时寻找鼠标位置
83 | resetMousePosition(){
84 | MouseMove(A_ScreenWidth/2, A_ScreenHeight/2)
85 | }
86 | ; 重置鼠标连点
87 | CapsLock & r::{
88 | resetMouseClick()
89 | }
90 |
91 | CapsLock & m::{
92 | resetMouseClick()
93 | global clickInterval
94 | wnhn := "W200 H100"
95 | timeInput := InputBox("鼠标点击的时间间隔(ms)", "默认为50ms" ,wnhn)
96 |
97 | if (timeInput.Result='Cancel'){
98 | return
99 | }else if (timeInput.Value <10){
100 | MsgBox('不能输入小于10的数')
101 | return
102 | }
103 | clickInterval:=timeInput.Value
104 |
105 | }
106 |
107 | ; 设置指针大小
108 | SPI_SETCURSORSIZE := 0x0071
109 |
110 | ; 指定所需的指针大小(例如,20)
111 | desiredSize := 50
112 |
113 | ; 调用 SystemParametersInfo 函数
114 | DllCall("SystemParametersInfo", "UInt", SPI_SETCURSORSIZE, "UInt", desiredSize, "Ptr", 0, "UInt", 0)
--------------------------------------------------------------------------------
/scripts/switchIME.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | windows自带输入法的id,可以通过调用windows api GetKeyboardLayout来获取
3 | 微软拼音输入法 134481924
4 | 微软日文输入法 68224017
5 | 微软英文输入法 67699721
6 | */
7 |
8 | ; 设置脚本是否可以 "看见" 隐藏的窗口
9 | DetectHiddenWindows True
10 |
11 | IMEmap:=Map(
12 | "zh",134481924,
13 | "jp",68224017,
14 | "en",67699721
15 | )
16 | ; enAppList :=[
17 | ; "pwsh.exe"
18 | ; ]
19 | ; 获取当前激活窗口所使用的IME的ID
20 | getCurrentIMEID(){
21 | winID:=winGetID("A")
22 | ThreadID:=DllCall("GetWindowThreadProcessId", "UInt", WinID, "UInt", 0)
23 | InputLocaleID:=DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
24 | return InputLocaleID
25 | }
26 | ; 使用IMEID激活对应的输入法
27 | switchIMEbyID(IMEID){
28 | winTitle:=WinGetTitle("A")
29 | PostMessage(0x50, 0, IMEID,, WinTitle )
30 | }
31 |
32 | ; 可以用于判断微软拼音是否是英文模式
33 | isEnglishMode(){
34 | hWnd := winGetID("A")
35 | result := SendMessage(
36 | 0x283, ; Message : WM_IME_CONTROL
37 | 0x001, ; wParam : IMC_GETCONVERSIONMODE
38 | 0, ; lParam : (NoArgs)
39 | , ; Control : (Window)
40 | ; 获取当前输入法的模式
41 | ; Retrieves the default window handle to the IME class.
42 | "ahk_id " DllCall("imm32\ImmGetDefaultIMEWnd", "Uint", hWnd, "Uint")
43 | )
44 | ; DetectHiddenWindows Fasle
45 | ; 返回值是0表示是英文模式,其他值表明是中文模式
46 | return result == 0
47 | }
48 |
49 | ; 切换微软拼音输入法
50 | CapsLock & 1::{
51 | switchIMEbyID(IMEmap["zh"])
52 | ; SetCapsLockState "alwaysoff"
53 | }
54 | ; 切换微软英文键盘
55 | CapsLock & 2::{
56 | switchIMEbyID(IMEmap["en"])
57 | ; SetCapsLockState "alwaysoff"
58 | }
59 | ; 切换微软日文输入法
60 | CapsLock & 3::{
61 | switchIMEbyID(IMEmap["jp"])
62 | ; SetCapsLockState "alwaysoff"
63 | }
64 |
65 | switchIMEThread(){
66 | ; 使用窗口组实现批量窗口的监视
67 | GroupAdd "enAppGroup", "ahk_exe pwsh.exe" ;添加powershell
68 | GroupAdd "enAppGroup", "ahk_exe Code.exe" ;添加 vscode
69 | GroupAdd "enAppGroup", "ahk_exe WindowsTerminal.exe" ;添加windows terminal
70 |
71 | ; 新版,用shift切换中英文模式,不需要安装另外的输入法
72 | Loop{
73 | try{
74 | WWAhwnd := WinWaitActive("ahk_group enAppGroup")
75 | }catch as e{
76 |
77 | ; TrayTip "switchIME winwaitactive error:" e.Message
78 | Sleep(1000)
79 | continue
80 | }
81 | if(WWAhwnd ==0 ){
82 | continue
83 | }else{
84 | try{
85 | currentWinTitle:=WinGetTitle(WWAhwnd)
86 | ; 排除用vscode等软件编辑markdown的情况,编辑markdown的时候大部分地方使用中文
87 | if (!RegExMatch(currentWinTitle,"\.md")){
88 | ; 在en组app里,如果是中文模式切换成英文
89 | if (!isEnglishMode()){
90 | send "{Shift}"
91 | }
92 | }
93 | ; 从当且窗口切出,进行下一轮监视
94 | ; try catch 避免因为突然关闭程序造成winwaitnotactive失效
95 |
96 | WinWaitNotActive(WWAhwnd)
97 | ; 切出en组app需要切回中文。
98 | if(isEnglishMode()){
99 | send "{Shift}"
100 | }
101 | }
102 | catch as e{
103 | Sleep(1000)
104 | continue
105 | }
106 | }
107 | }
108 | }
109 |
110 | switchIMEThread()
--------------------------------------------------------------------------------
/.promptx/resource/domain/autohotkey-expert/execution/autohotkey-workflow.execution.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## AutoHotkey开发约束
4 | - **语法规范**:严格遵循AutoHotkey语法规则
5 | - **版本兼容**:明确指定适用的AHK版本(v1或v2)
6 | - **系统要求**:确保脚本在目标Windows版本上运行
7 | - **权限限制**:考虑UAC和管理员权限要求
8 | - **性能约束**:避免过度消耗系统资源
9 |
10 |
11 |
12 | ## 强制性开发规则
13 | - **错误处理**:所有脚本必须包含适当的错误处理机制
14 | - **注释规范**:关键代码段必须有清晰的中文注释
15 | - **变量命名**:使用有意义的变量名,遵循驼峰命名法
16 | - **函数封装**:复杂逻辑必须封装为独立函数
17 | - **测试验证**:提供测试方法和验证步骤
18 |
19 |
20 |
21 | ## 开发指导原则
22 | - **用户友好**:优先考虑用户体验和易用性
23 | - **渐进开发**:从简单版本开始,逐步增加功能
24 | - **文档完整**:提供详细的使用说明和示例
25 | - **社区标准**:遵循AutoHotkey社区的最佳实践
26 |
27 |
28 |
29 | ## AutoHotkey专家标准工作流程
30 |
31 | ### 阶段1:需求分析与方案设计(10-15分钟)
32 |
33 | #### 1.1 需求理解
34 | ```
35 | 📋 需求收集清单:
36 | □ 具体要实现什么功能?
37 | □ 触发条件是什么?(热键、时间、事件)
38 | □ 目标应用程序或窗口是什么?
39 | □ 期望的执行效果是什么?
40 | □ 有什么特殊要求或限制?
41 | ```
42 |
43 | #### 1.2 技术评估
44 | ```
45 | 🔍 技术可行性检查:
46 | □ AutoHotkey是否适合解决此问题?
47 | □ 需要哪些核心功能模块?
48 | □ 是否需要调用外部API或DLL?
49 | □ 预估开发复杂度和时间?
50 | □ 可能遇到的技术难点?
51 | ```
52 |
53 | #### 1.3 方案设计
54 | ```
55 | 📐 设计方案模板:
56 | 1. 核心功能模块划分
57 | 2. 主要函数和变量设计
58 | 3. 用户交互方式设计
59 | 4. 错误处理策略
60 | 5. 性能优化考虑
61 | ```
62 |
63 | ### 阶段2:核心开发实现(20-30分钟)
64 |
65 | #### 2.1 基础框架搭建
66 | ```autohotkey
67 | ; AutoHotkey脚本基础模板
68 | #NoEnv
69 | #SingleInstance Force
70 | #Persistent
71 | SendMode Input
72 | SetWorkingDir %A_ScriptDir%
73 |
74 | ; 全局变量定义
75 | ; 配置参数设置
76 | ; 错误处理函数
77 | ```
78 |
79 | #### 2.2 核心功能实现
80 | ```
81 | 🛠️ 开发步骤:
82 | 1. 实现核心逻辑函数
83 | 2. 添加热键或触发机制
84 | 3. 集成窗口操作功能
85 | 4. 实现用户交互界面(如需要)
86 | 5. 添加配置和设置功能
87 | ```
88 |
89 | #### 2.3 错误处理与优化
90 | ```autohotkey
91 | ; 标准错误处理模板
92 | try {
93 | ; 主要逻辑代码
94 | } catch e {
95 | MsgBox, 16, 错误, 执行出错:%e.message%
96 | return
97 | }
98 | ```
99 |
100 | ### 阶段3:测试验证与完善(10-15分钟)
101 |
102 | #### 3.1 功能测试
103 | ```
104 | ✅ 测试检查清单:
105 | □ 基本功能是否正常工作?
106 | □ 热键是否响应正确?
107 | □ 窗口识别是否准确?
108 | □ 错误情况是否正确处理?
109 | □ 性能是否满足要求?
110 | ```
111 |
112 | #### 3.2 兼容性验证
113 | ```
114 | 🔧 兼容性检查:
115 | □ 在目标系统版本上测试
116 | □ 检查AHK版本兼容性
117 | □ 验证权限要求
118 | □ 测试多显示器环境(如适用)
119 | ```
120 |
121 | #### 3.3 用户体验优化
122 | ```
123 | 💡 优化要点:
124 | □ 添加操作提示和反馈
125 | □ 优化执行速度和响应时间
126 | □ 简化配置和使用流程
127 | □ 提供帮助信息和说明
128 | ```
129 |
130 | ### 阶段4:文档交付与支持(5-10分钟)
131 |
132 | #### 4.1 使用文档
133 | ```markdown
134 | # 脚本使用说明
135 |
136 | ## 功能描述
137 | [详细描述脚本功能]
138 |
139 | ## 使用方法
140 | 1. [安装步骤]
141 | 2. [配置方法]
142 | 3. [使用说明]
143 |
144 | ## 注意事项
145 | - [重要提醒]
146 | - [常见问题]
147 |
148 | ## 故障排除
149 | [问题解决方案]
150 | ```
151 |
152 | #### 4.2 代码注释完善
153 | ```autohotkey
154 | ; ===== 脚本信息 =====
155 | ; 脚本名称:[名称]
156 | ; 功能描述:[描述]
157 | ; 作者:AutoHotkey专家
158 | ; 版本:1.0
159 | ; 更新日期:[日期]
160 | ; ==================
161 | ```
162 |
163 | ## 🔧 常用开发模式
164 |
165 | ### 热键脚本模式
166 | ```autohotkey
167 | ; 热键定义模板
168 | F1::
169 | ; 功能实现
170 | return
171 |
172 | ; 组合热键
173 | Ctrl+Alt+T::
174 | ; 功能实现
175 | return
176 | ```
177 |
178 | ### 窗口操作模式
179 | ```autohotkey
180 | ; 窗口操作模板
181 | WinActivate, 窗口标题
182 | WinWaitActive, 窗口标题, , 3
183 | if ErrorLevel {
184 | MsgBox, 无法激活目标窗口
185 | return
186 | }
187 | ; 后续操作
188 | ```
189 |
190 | ### GUI界面模式
191 | ```autohotkey
192 | ; GUI创建模板
193 | Gui, Add, Text, , 说明文字
194 | Gui, Add, Edit, vUserInput w200
195 | Gui, Add, Button, gButtonClick, 确定
196 | Gui, Show, , 窗口标题
197 | return
198 |
199 | ButtonClick:
200 | Gui, Submit
201 | ; 处理用户输入
202 | return
203 | ```
204 |
205 | ## 📊 质量标准
206 |
207 | ### 代码质量指标
208 | - ✅ 代码可读性:注释覆盖率 ≥ 30%
209 | - ✅ 错误处理:关键操作100%包含错误处理
210 | - ✅ 性能要求:响应时间 ≤ 500ms
211 | - ✅ 兼容性:支持Windows 10/11
212 |
213 | ### 用户体验指标
214 | - ✅ 易用性:普通用户可独立使用
215 | - ✅ 稳定性:连续运行无异常
216 | - ✅ 反馈性:操作有明确反馈
217 | - ✅ 文档性:提供完整使用说明
218 |
219 |
220 |
221 | ## 交付标准
222 |
223 | ### 必备要素
224 | - ✅ 功能完整实现
225 | - ✅ 错误处理完善
226 | - ✅ 代码注释清晰
227 | - ✅ 使用说明详细
228 |
229 | ### 质量要求
230 | - ✅ 代码规范标准
231 | - ✅ 性能满足需求
232 | - ✅ 兼容性良好
233 | - ✅ 用户体验友好
234 |
235 | ### 文档要求
236 | - ✅ 功能说明完整
237 | - ✅ 使用步骤清晰
238 | - ✅ 注意事项明确
239 | - ✅ 故障排除指南
240 |
241 |
--------------------------------------------------------------------------------
/install-autohotkey.ps1:
--------------------------------------------------------------------------------
1 | # AutoHotkey 2.0 自动安装脚本
2 | # 此脚本将自动下载并安装最新版本的 AutoHotkey 2.0
3 |
4 | param(
5 | [switch]$Force,
6 | [switch]$Silent
7 | )
8 |
9 | # 检查管理员权限
10 | function Test-Administrator {
11 | $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
12 | $principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
13 | return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
14 | }
15 |
16 | # 获取最新版本信息
17 | function Get-LatestAHKVersion {
18 | try {
19 | Write-Host "正在获取 AutoHotkey 2.0 最新版本信息..." -ForegroundColor Yellow
20 | $apiUrl = "https://api.github.com/repos/AutoHotkey/AutoHotkey/releases/latest"
21 | $response = Invoke-RestMethod -Uri $apiUrl -UseBasicParsing
22 |
23 | # 查找 .exe 安装包
24 | $asset = $response.assets | Where-Object { $_.name -like "*_setup.exe" -and $_.name -notlike "*_x64_setup.exe" }
25 |
26 | if ($asset) {
27 | return @{
28 | Version = $response.tag_name
29 | DownloadUrl = $asset.browser_download_url
30 | FileName = $asset.name
31 | }
32 | } else {
33 | throw "未找到合适的安装包"
34 | }
35 | }
36 | catch {
37 | Write-Error "获取版本信息失败: $($_.Exception.Message)"
38 | return $null
39 | }
40 | }
41 |
42 | # 检查是否已安装 AutoHotkey
43 | function Test-AHKInstalled {
44 | $ahkPath = Get-Command "AutoHotkey.exe" -ErrorAction SilentlyContinue
45 | if ($ahkPath) {
46 | try {
47 | $version = & $ahkPath.Source "--version" 2>$null
48 | if ($version -match "v2\.") {
49 | Write-Host "检测到已安装 AutoHotkey 2.0: $version" -ForegroundColor Green
50 | return $true
51 | }
52 | }
53 | catch {
54 | # 忽略版本检查错误
55 | }
56 | }
57 |
58 | # 检查注册表
59 | $regPaths = @(
60 | "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
61 | "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
62 | )
63 |
64 | foreach ($regPath in $regPaths) {
65 | $installed = Get-ItemProperty $regPath -ErrorAction SilentlyContinue |
66 | Where-Object { $_.DisplayName -like "*AutoHotkey*" -and $_.DisplayVersion -like "2.*" }
67 | if ($installed) {
68 | Write-Host "检测到已安装 AutoHotkey 2.0: $($installed.DisplayVersion)" -ForegroundColor Green
69 | return $true
70 | }
71 | }
72 |
73 | return $false
74 | }
75 |
76 | # 下载文件
77 | function Download-File {
78 | param(
79 | [string]$Url,
80 | [string]$OutputPath
81 | )
82 |
83 | try {
84 | Write-Host "正在下载: $Url" -ForegroundColor Yellow
85 |
86 | # 使用 WebClient 下载并显示进度
87 | $webClient = New-Object System.Net.WebClient
88 | $webClient.DownloadFile($Url, $OutputPath)
89 | $webClient.Dispose()
90 |
91 | Write-Host "下载完成: $OutputPath" -ForegroundColor Green
92 | return $true
93 | }
94 | catch {
95 | Write-Error "下载失败: $($_.Exception.Message)"
96 | return $false
97 | }
98 | }
99 |
100 | # 安装 AutoHotkey
101 | function Install-AutoHotkey {
102 | param(
103 | [string]$InstallerPath,
104 | [bool]$Silent
105 | )
106 |
107 | try {
108 | Write-Host "正在安装 AutoHotkey 2.0..." -ForegroundColor Yellow
109 |
110 | $arguments = if ($Silent) { "/S" } else { "" }
111 | $process = Start-Process -FilePath $InstallerPath -ArgumentList $arguments -Wait -PassThru
112 |
113 | if ($process.ExitCode -eq 0) {
114 | Write-Host "AutoHotkey 2.0 安装成功!" -ForegroundColor Green
115 | return $true
116 | } else {
117 | Write-Error "安装失败,退出代码: $($process.ExitCode)"
118 | return $false
119 | }
120 | }
121 | catch {
122 | Write-Error "安装过程中发生错误: $($_.Exception.Message)"
123 | return $false
124 | }
125 | }
126 |
127 | # 主函数
128 | function Main {
129 | Write-Host "=== AutoHotkey 2.0 自动安装脚本 ===" -ForegroundColor Cyan
130 | Write-Host ""
131 |
132 | # 检查管理员权限
133 | if (-not (Test-Administrator)) {
134 | Write-Warning "建议以管理员身份运行此脚本以确保正确安装"
135 | if (-not $Force) {
136 | $response = Read-Host "是否继续? (y/N)"
137 | if ($response -ne 'y' -and $response -ne 'Y') {
138 | Write-Host "安装已取消" -ForegroundColor Yellow
139 | return
140 | }
141 | }
142 | }
143 |
144 | # 检查是否已安装
145 | if ((Test-AHKInstalled) -and (-not $Force)) {
146 | Write-Host "AutoHotkey 2.0 已安装,使用 -Force 参数强制重新安装" -ForegroundColor Yellow
147 | return
148 | }
149 |
150 | # 获取最新版本
151 | $versionInfo = Get-LatestAHKVersion
152 | if (-not $versionInfo) {
153 | Write-Error "无法获取版本信息,安装终止"
154 | return
155 | }
156 |
157 | Write-Host "最新版本: $($versionInfo.Version)" -ForegroundColor Green
158 | Write-Host "下载地址: $($versionInfo.DownloadUrl)" -ForegroundColor Gray
159 |
160 | # 创建临时目录
161 | $tempDir = Join-Path $env:TEMP "AHK_Install"
162 | if (-not (Test-Path $tempDir)) {
163 | New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
164 | }
165 |
166 | $installerPath = Join-Path $tempDir $versionInfo.FileName
167 |
168 | # 下载安装包
169 | if (-not (Download-File -Url $versionInfo.DownloadUrl -OutputPath $installerPath)) {
170 | Write-Error "下载失败,安装终止"
171 | return
172 | }
173 |
174 | # 安装
175 | if (Install-AutoHotkey -InstallerPath $installerPath -Silent $Silent) {
176 | Write-Host ""
177 | Write-Host "=== 安装完成 ===" -ForegroundColor Green
178 | Write-Host "请重新启动 PowerShell 或命令提示符以使用 AutoHotkey 命令" -ForegroundColor Yellow
179 |
180 | # 验证安装
181 | Start-Sleep -Seconds 2
182 | if (Test-AHKInstalled) {
183 | Write-Host "✓ 安装验证成功" -ForegroundColor Green
184 | } else {
185 | Write-Warning "安装验证失败,请手动检查安装状态"
186 | }
187 | }
188 |
189 | # 清理临时文件
190 | try {
191 | Remove-Item $installerPath -Force -ErrorAction SilentlyContinue
192 | Write-Host "临时文件已清理" -ForegroundColor Gray
193 | }
194 | catch {
195 | Write-Warning "清理临时文件失败: $($_.Exception.Message)"
196 | }
197 | }
198 |
199 | # 执行主函数
200 | Main
201 |
202 | Write-Host ""
203 | Write-Host "脚本执行完成,按任意键退出..." -ForegroundColor Cyan
204 | $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
--------------------------------------------------------------------------------
/makeScripts.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 5.0
2 | <#
3 | .SYNOPSIS
4 | AutoHotkey 脚本构建和部署工具
5 |
6 | .DESCRIPTION
7 | 将 scripts 目录下的所有 AutoHotkey 脚本合并为单个脚本文件,
8 | 并可选择性地创建启动快捷方式以实现开机自启动。
9 |
10 | .PARAMETER ScriptName
11 | 输出的脚本文件名,默认为 'myAllScripts.ahk'
12 |
13 | .PARAMETER StartUpFolder
14 | 启动文件夹路径,如果不指定则使用用户启动目录
15 |
16 | .PARAMETER ConcatNotInclude
17 | 使用完整拼接模式而非 #include 模式
18 |
19 | .PARAMETER UseUserStartup
20 | 使用用户启动目录而非系统启动目录(推荐)
21 |
22 | .PARAMETER Force
23 | 强制覆盖现有文件
24 |
25 | .PARAMETER NoAutoStart
26 | 不自动启动生成的脚本
27 |
28 | .PARAMETER Verbose
29 | 显示详细输出信息
30 |
31 | .EXAMPLE
32 | .\makeScripts.ps1
33 | 使用默认设置构建脚本
34 |
35 | .EXAMPLE
36 | .\makeScripts.ps1 -ScriptName "MyCustomScript.ahk" -UseUserStartup -Verbose
37 | 自定义脚本名并使用用户启动目录
38 | #>
39 |
40 | param(
41 | [ValidatePattern('.*\.ahk$')]
42 | [string]$ScriptName = 'myAllScripts.ahk',
43 |
44 | [ValidateScript({Test-Path $_ -IsValid})]
45 | [string]$StartUpFolder,
46 |
47 | [switch]$ConcatNotInclude,
48 | [switch]$UseUserStartup = $true,
49 | [switch]$Force,
50 | [switch]$NoAutoStart,
51 | [switch]$Verbose
52 | )
53 | # ==================== 配置管理 ====================
54 |
55 | # 加载配置文件
56 | function Get-BuildConfiguration {
57 | param([string]$ConfigPath = "./build.config.json")
58 |
59 | try {
60 | if (Test-Path $ConfigPath) {
61 | $configContent = Get-Content -Path $ConfigPath -Raw -Encoding UTF8
62 | $config = $configContent | ConvertFrom-Json
63 | Write-BuildLog "配置文件已加载: $ConfigPath" "Info"
64 | return $config
65 | } else {
66 | Write-BuildLog "配置文件不存在,使用默认设置: $ConfigPath" "Warning"
67 | return $null
68 | }
69 | }
70 | catch {
71 | Write-BuildLog "加载配置文件失败: $($_.Exception.Message)" "Error"
72 | return $null
73 | }
74 | }
75 |
76 | # 合并配置和参数
77 | function Merge-Configuration {
78 | param(
79 | [object]$Config,
80 | [hashtable]$Parameters
81 | )
82 |
83 | if (-not $Config) {
84 | return $Parameters
85 | }
86 |
87 | # 从配置文件中读取默认值,如果参数未指定则使用配置文件的值
88 | $merged = @{}
89 |
90 | # 构建设置
91 | $merged.ScriptsPath = if ($Parameters.ContainsKey('ScriptsPath')) { $Parameters.ScriptsPath } else { $Config.build.scriptsPath }
92 | $merged.BasePath = if ($Parameters.ContainsKey('BasePath')) { $Parameters.BasePath } else { $Config.build.basePath }
93 | $merged.OutputPath = if ($Parameters.ContainsKey('OutputPath')) { $Parameters.OutputPath } else { $Config.build.outputPath }
94 | $merged.UseInclude = if ($Parameters.ContainsKey('ConcatNotInclude')) { -not $Parameters.ConcatNotInclude } else { $Config.build.useInclude }
95 |
96 | # 快捷方式设置
97 | $merged.CreateShortcut = if ($Parameters.ContainsKey('CreateShortcut')) { $Parameters.CreateShortcut } else { $Config.shortcuts.createShortcut }
98 | $merged.UseUserStartup = if ($Parameters.ContainsKey('UseUserStartup')) { $Parameters.UseUserStartup } else { $Config.shortcuts.useUserStartup }
99 |
100 | # 执行设置
101 | $merged.AutoStart = if ($Parameters.ContainsKey('NoAutoStart')) { -not $Parameters.NoAutoStart } else { $Config.execution.autoStart }
102 | $merged.Force = if ($Parameters.ContainsKey('Force')) { $Parameters.Force } else { $Config.execution.force }
103 | $merged.Verbose = if ($Parameters.ContainsKey('Verbose')) { $Parameters.Verbose } else { $Config.execution.verbose }
104 |
105 | return $merged
106 | }
107 |
108 | # ==================== 辅助函数 ====================
109 |
110 | # 检查管理员权限
111 | function Test-Administrator {
112 | $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
113 | $principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
114 | return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
115 | }
116 |
117 | # 写入构建日志
118 | function Write-BuildLog {
119 | param(
120 | [string]$Message,
121 | [ValidateSet("Info", "Warning", "Error", "Success")]
122 | [string]$Level = "Info"
123 | )
124 |
125 | $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
126 | $logEntry = "[$timestamp] [$Level] $Message"
127 |
128 | if ($Verbose) {
129 | Add-Content -Path "build.log" -Value $logEntry -ErrorAction SilentlyContinue
130 | }
131 |
132 | switch ($Level) {
133 | "Error" {
134 | Write-Host "✗ $Message" -ForegroundColor Red
135 | Write-Error $Message
136 | }
137 | "Warning" {
138 | Write-Host "⚠ $Message" -ForegroundColor Yellow
139 | }
140 | "Success" {
141 | Write-Host "✓ $Message" -ForegroundColor Green
142 | }
143 | default {
144 | if ($Verbose) {
145 | Write-Host "ℹ $Message" -ForegroundColor Cyan
146 | }
147 | }
148 | }
149 | }
150 |
151 | # 创建快捷方式
152 | function New-Shortcut {
153 | param(
154 | [string]$TargetPath,
155 | [string]$SourcePath
156 | )
157 |
158 | try {
159 | $shell = New-Object -ComObject WScript.Shell
160 | $shortcut = $shell.CreateShortcut($TargetPath)
161 | $shortcut.TargetPath = $SourcePath
162 | $shortcut.WorkingDirectory = Split-Path $SourcePath -Parent
163 | $shortcut.Description = "AutoHotkey 自动启动脚本"
164 | $shortcut.Save()
165 |
166 | # 释放 COM 对象
167 | [System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) | Out-Null
168 |
169 | Write-BuildLog "快捷方式创建成功: $TargetPath" "Success"
170 | return $true
171 | }
172 | catch {
173 | Write-BuildLog "创建快捷方式失败: $($_.Exception.Message)" "Error"
174 | return $false
175 | }
176 | }
177 |
178 | # 验证 AutoHotkey 安装
179 | function Test-AutoHotkeyInstalled {
180 | $ahkCommand = Get-Command "AutoHotkey.exe" -ErrorAction SilentlyContinue
181 | if ($ahkCommand) {
182 | try {
183 | $version = & $ahkCommand.Source "--version" 2>$null
184 | if ($version -match "v2\.") {
185 | Write-BuildLog "检测到 AutoHotkey 2.0: $version" "Success"
186 | return $true
187 | }
188 | }
189 | catch {
190 | # 忽略版本检查错误
191 | }
192 | }
193 |
194 | Write-BuildLog "未检测到 AutoHotkey 2.0,请先运行 install-autohotkey.ps1" "Warning"
195 | return $false
196 | }
197 |
198 | # 获取启动文件夹路径
199 | function Get-StartupFolderPath {
200 | if ($StartUpFolder) {
201 | return $StartUpFolder
202 | }
203 |
204 | if ($UseUserStartup) {
205 | return "$Env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
206 | } else {
207 | # 检查是否有管理员权限
208 | if (-not (Test-Administrator)) {
209 | Write-BuildLog "写入系统启动目录需要管理员权限,切换到用户启动目录" "Warning"
210 | return "$Env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
211 | }
212 | return "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp"
213 | }
214 | }
215 | # ==================== 主要构建逻辑 ====================
216 |
217 | # 获取 AHK 脚本文件
218 | function Get-AhkScripts {
219 | param([string]$ScriptsPath = "./Scripts")
220 |
221 | try {
222 | if (-not (Test-Path $ScriptsPath)) {
223 | Write-BuildLog "脚本目录不存在: $ScriptsPath" "Error"
224 | return @()
225 | }
226 |
227 | $scripts = Get-ChildItem -Recurse -Path $ScriptsPath -Filter "*.ahk" -ErrorAction Stop
228 | Write-BuildLog "找到 $($scripts.Count) 个 AHK 脚本文件" "Info"
229 |
230 | return $scripts
231 | }
232 | catch {
233 | Write-BuildLog "获取脚本文件失败: $($_.Exception.Message)" "Error"
234 | return @()
235 | }
236 | }
237 |
238 | # 构建脚本内容
239 | function Build-AhkScript {
240 | param(
241 | [array]$Scripts,
242 | [bool]$UseInclude = $true
243 | )
244 |
245 | $includeString = ''
246 | $processedCount = 0
247 |
248 | foreach ($script in $Scripts) {
249 | try {
250 | $processedCount++
251 |
252 | if ($Verbose) {
253 | Write-Progress -Activity "构建 AHK 脚本" -Status "处理: $($script.Name)" -PercentComplete (($processedCount / $Scripts.Count) * 100)
254 | }
255 |
256 | if ($UseInclude) {
257 | # 使用 #include 模式
258 | $includeString += "#include `"$($script.FullName)`"`n"
259 | Write-BuildLog "添加包含: $($script.Name)" "Info"
260 | } else {
261 | # 使用完整拼接模式
262 | $ahkContent = Get-Content -Path $script.FullName -Raw -Encoding UTF8
263 | if ($ahkContent) {
264 | $includeString += "; ==================== $($script.Name) ====================`n"
265 | $includeString += $ahkContent + "`n`n"
266 | Write-BuildLog "拼接内容: $($script.Name)" "Info"
267 | }
268 | }
269 | }
270 | catch {
271 | Write-BuildLog "处理脚本文件失败 $($script.Name): $($_.Exception.Message)" "Warning"
272 | continue
273 | }
274 | }
275 |
276 | if ($Verbose) {
277 | Write-Progress -Activity "构建 AHK 脚本" -Completed
278 | }
279 |
280 | return $includeString
281 | }
282 |
283 | # 主构建函数
284 | function Invoke-ScriptBuild {
285 | Write-BuildLog "开始构建 AutoHotkey 脚本" "Info"
286 |
287 | # 检查 AutoHotkey 安装
288 | Test-AutoHotkeyInstalled | Out-Null
289 |
290 | # 检查输出文件是否存在
291 | if ((Test-Path $ScriptName) -and (-not $Force)) {
292 | $response = Read-Host "文件 '$ScriptName' 已存在,是否覆盖? (y/N)"
293 | if ($response -ne 'y' -and $response -ne 'Y') {
294 | Write-BuildLog "构建已取消" "Warning"
295 | return $false
296 | }
297 | }
298 |
299 | # 获取脚本文件
300 | $scripts = Get-AhkScripts
301 | if ($scripts.Count -eq 0) {
302 | Write-BuildLog "未找到任何 AHK 脚本文件" "Error"
303 | return $false
304 | }
305 |
306 | # 读取基础脚本
307 | try {
308 | if (Test-Path ".\base.ahk") {
309 | $baseContent = Get-Content ".\base.ahk" -Raw -Encoding UTF8
310 | Write-BuildLog "加载基础脚本: base.ahk" "Info"
311 | } else {
312 | $baseContent = "; AutoHotkey 2.0 自动生成脚本`n; 生成时间: $(Get-Date)`n`n"
313 | Write-BuildLog "未找到 base.ahk,使用默认头部" "Warning"
314 | }
315 | }
316 | catch {
317 | Write-BuildLog "读取基础脚本失败: $($_.Exception.Message)" "Error"
318 | return $false
319 | }
320 |
321 | # 构建脚本内容
322 | $includeContent = Build-AhkScript -Scripts $scripts -UseInclude (-not $ConcatNotInclude)
323 | $finalContent = $baseContent + "`n" + $includeContent
324 |
325 | # 写入输出文件
326 | try {
327 | Out-File -InputObject $finalContent -Encoding UTF8 -FilePath $ScriptName -ErrorAction Stop
328 | Write-BuildLog "脚本构建成功: $ScriptName" "Success"
329 | return $true
330 | }
331 | catch {
332 | Write-BuildLog "写入输出文件失败: $($_.Exception.Message)" "Error"
333 | return $false
334 | }
335 | }
336 |
337 | # ==================== 主执行逻辑 ====================
338 |
339 | # 加载配置文件
340 | $config = Get-BuildConfiguration
341 |
342 | # 合并配置和命令行参数
343 | $currentParams = @{
344 | ScriptName = $ScriptName
345 | ConcatNotInclude = $ConcatNotInclude
346 | CreateShortcut = $CreateShortcut
347 | UseUserStartup = $UseUserStartup
348 | Force = $Force
349 | NoAutoStart = $NoAutoStart
350 | Verbose = $Verbose
351 | }
352 |
353 | $mergedConfig = Merge-Configuration -Config $config -Parameters $currentParams
354 |
355 | # 应用合并后的配置
356 | if ($config) {
357 | $script:ScriptName = $mergedConfig.OutputPath
358 | $script:ConcatNotInclude = -not $mergedConfig.UseInclude
359 | $script:CreateShortcut = $mergedConfig.CreateShortcut
360 | $script:UseUserStartup = $mergedConfig.UseUserStartup
361 | $script:Force = $mergedConfig.Force
362 | $script:NoAutoStart = -not $mergedConfig.AutoStart
363 | $script:Verbose = $mergedConfig.Verbose
364 | }
365 |
366 | try {
367 | Write-BuildLog "=== AutoHotkey 脚本构建工具 ===" "Info"
368 | Write-BuildLog "输出文件: $ScriptName" "Info"
369 | Write-BuildLog "使用包含模式: $(-not $ConcatNotInclude)" "Info"
370 |
371 | # 执行构建
372 | $buildSuccess = Invoke-ScriptBuild
373 |
374 | if (-not $buildSuccess) {
375 | Write-BuildLog "脚本构建失败,退出" "Error"
376 | exit 1
377 | }
378 |
379 | # 获取启动文件夹路径
380 | $startupPath = Get-StartupFolderPath
381 | if (-not $startupPath) {
382 | Write-BuildLog "无法确定启动文件夹路径" "Error"
383 | exit 1
384 | }
385 |
386 | # 创建快捷方式
387 | if ($CreateShortcut) {
388 | $linkName = [System.IO.Path]::GetFileNameWithoutExtension($ScriptName) + ".lnk"
389 | $linkPath = Join-Path -Path $startupPath -ChildPath $linkName
390 |
391 | if ((Test-Path -Path $linkPath) -and (-not $Force)) {
392 | Write-BuildLog "快捷方式已存在: $linkPath" "Info"
393 | } else {
394 | $shortcutSuccess = New-Shortcut -LinkPath $linkPath -TargetPath (Resolve-Path $ScriptName).Path
395 |
396 | if ($shortcutSuccess) {
397 | Write-BuildLog "快捷方式已创建: $linkPath" "Success"
398 | } else {
399 | Write-BuildLog "快捷方式创建失败" "Warning"
400 | }
401 | }
402 | }
403 |
404 | # 自动启动脚本
405 | if (-not $NoAutoStart) {
406 | try {
407 | Write-BuildLog "启动 AutoHotkey 脚本..." "Info"
408 | Start-Process -FilePath $ScriptName -ErrorAction Stop
409 | Write-BuildLog "脚本已启动: $ScriptName" "Success"
410 | }
411 | catch {
412 | Write-BuildLog "启动脚本失败: $($_.Exception.Message)" "Error"
413 | }
414 | }
415 |
416 | Write-BuildLog "所有操作完成" "Success"
417 | }
418 | catch {
419 | Write-BuildLog "执行过程中发生错误: $($_.Exception.Message)" "Error"
420 | exit 1
421 | }
422 | finally {
423 | # 清理临时文件或资源
424 | if ($Verbose) {
425 | Write-BuildLog "清理完成" "Info"
426 | }
427 | }
--------------------------------------------------------------------------------