├── 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 | } --------------------------------------------------------------------------------