virtual-machine - 我的 AutoHotKey 脚本如何相应地启动批处理脚本?
问题描述
该脚本应该将我从 Windows 切换到 Linux(VM),反之亦然:
Pause::vmStart()
return
runVM := false
linux := false
vmStart()
{
If (!runVM and !linux) {
Run, C:\Users\patrick\dev-vm\PS.cmd
runVM := true
sleep, 18000
}
If (!linux and !WinExist("DevVM - 127.0.0.1:23389 - RDP")) {
Run, C:\Users\patrick\dev-vm\RDP.cmd
}
if (!linux) {
WinShow, DevVM - 127.0.0.1:23389 - RDP
WinActivate, DevVM - 127.0.0.1:23389 - RDP
}
Send ^!{CtrlBreak}
linux := !linux
}
- 当我在 Windows 中时,它需要先激活我的 RDP 窗口(什么工作正常)。
- 当我在 Windows 中并且 VM 没有使用 PS.cmd 启动时,它应该启动它(这也有效,大约需要 18 秒)
- 使用 ^!{CtrlBreak} 也是正常的开关。
我认为我的括号/函数/布尔定义有问题。你发现错误了吗?
解决方案
有一些问题,但只有一个很重要。
首先,您的变量定义是无法访问的代码。
Pause::vmStart()
return
runVM := false
linux := false
代码执行在遇到的第一个热键处停止。
此外,你还有一个Return
在那里,它也会停止代码执行。所以你真的要确保代码执行永远不会到达变量定义哈哈。
幸运的是,AHK 非常宽容,如果您引用任何尚未声明的变量,它会使用默认值nothing创建,其计算结果也为false。
所以这不是真正的问题,但仍然需要修复。将定义移动到热键上方,或者只是删除它们,由于 AHK 的宽容度,因此不需要它们,如上所述。
然后到下一个问题,变量范围。
在该函数的范围内,您引用的变量不存在,并且每次运行该函数时都会创建和释放它们。
你有几个选项可以做。您可以将变量定义为global、static或super global(super global 是不好的做法,不推荐)。
将它们定义为全局意味着您引用了在函数范围之外找到的变量,并且其值将存储在那里。要将变量定义为全局变量,您可以让函数的第一行执行以下操作:
vmStart()
{
global runVM, linux
...
或者你可以让函数的第一行只是关键字global
,这意味着函数假定所有变量都是全局的。
要将变量定义为静态变量,您可以执行与 global 相同的操作(使用关键字static
)。将它们定义为静态基本上意味着它们在函数完成执行后不会被释放。所以下次你调用函数时,它们的值就是你上次在函数中设置的值。
要将它们定义为超级全局,您可以使用如下关键字定义函数外部(在脚本的最顶部)的变量global
:
global runVM := false
global linux := false
Pause::vmStart()
...
这意味着任何试图通过该名称引用变量的范围都将使用您的超级全局变量。这是一种不好的做法,而且这样做很危险,尤其是在您使用外部库的情况下。不小心弄坏东西不会太难。
当然,当您有这样的小脚本时,无论您使用什么方法都没有区别。即使我承认有时在我的个人脚本上使用超级全局,只是因为不必担心范围非常方便。
如果您想听听我的建议,我会说选择静态变量。
它几乎完全适用于您在这里所做的事情。
这是您的成品(有一些杂项更改),以防我解释得不够好:
Pause::vmStart()
;the 'return' here did nothing for us, removed
vmStart()
{
;using the static keyword to make the function assume
;all variables are static, and also skipped even
;declaring the variables, not needed due to how forgiving AHK is
static
;got rid of the 'and' keyword in your if statements
;that's legacy syntax, big ew, it's not 2005
If (!runVM && !linux) {
Run, C:\Users\patrick\dev-vm\PS.cmd
runVM := true
sleep, 18000
}
;removed braces, one-liner statments don't need them
;just personal preference though, of course
If (!linux && !WinExist("DevVM - 127.0.0.1:23389 - RDP"))
Run, C:\Users\patrick\dev-vm\RDP.cmd
if (!linux) {
WinShow, DevVM - 127.0.0.1:23389 - RDP
WinActivate, DevVM - 127.0.0.1:23389 - RDP
}
;switched to SendInput, it's faster and more reliable
SendInput, ^!{CtrlBreak}
linux := !linux
}
推荐阅读
- python - 使用 pygrib 写入插值 grib2 数据会导致 grib 文件不可用
- git - 如何挑选作者所做的所有提交?
- requirejs - PDF.js 使用 RequireJS 呈现不正确的字符
- regex - 使用正则表达式匹配模式,如
狗 猫 - bucket - 有没有办法只提取元数据和 grib 中的特定范围?
- java - Bean 属性 'sakilaDao' 不可写或具有无效的 setter 方法。setter 的参数类型是否与 getter 的返回类型匹配?
- typescript - 如何从 nodejs 服务器的 react-native-webview 获取数据?
- python - discord.py 自定义嵌入命令没有响应
- c++ - 如何将文件读入元组向量?
- java - 初始化时将函数传递给类(java)