我的AutoHotKey脚本如何相应地启动批处理脚本? [英] How can my AutoHotKey script launch batch scripts accordingly?

查看:462
本文介绍了我的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,这也将停止代码执行.因此,您确实要确保代码执行永远不会达到变量定义haha.
幸运的是,AHK是超级宽容的,如果您引用尚未声明的任何变量,则会使用默认值 nothing 创建该变量,该默认值还会计算为 false .

所以这不是实际的问题,但是仍然需要解决.如前所述,将定义移到热键上方,或将其删除,由于AHK的宽容程度,因此不需要它们.
然后进入下一个问题,可变范围.

在该函数的作用域中,您引用的变量不存在,并且每次运行该函数时都会创建并释放它们.
您可以选择几种方法.您可以将变量定义为全局

This script is supposed to switch me from Windows to Linux(VM) and vice versa:

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
}

I think that there is something wrong with my brackets/function/boolean definition. Do you find the mistake?

解决方案

Has a few problems, but just one that matters.
Firstly, your variable definitions are unreachable code.

Pause::vmStart()
return

runVM := false
linux := false

Code execution stops at the first hotkey that is met.
In addition you also have a Return in there, which would also stop code execution. So you really are making sure code execution will never reach the variable definitions haha.
Luckily AHK is super forgiving and if you reference any variable that hasn't been declared yet, it's created with the default value of nothing, which also evaluates to false.

So that wasn't the actual problem, but still something that needs fixing. Move the definitions to be above your hotkey, or just remove them, they're not needed due to how forgiving AHK is, as explained above.
Then onto the next problem, variable scope.

In that function's scope the variables you reference don't exist, and they're created and freed every time you run the function.
You have a few options you can do. You can either define the variables as
global, static, or super global (super global is bad practice and not recommended).

Defining them as global means you reference a variable that's found outside of the function's scope and its value will be stored there. To define the variables as global, you'd make the first line(s) of your function do that like this:

vmStart()
{
    global runVM, linux
    ...

Or you could just make the first line of function be nothing but the keyword global, and that means the function assumes all variables are global.

To define the variables as static, you'd do the same as for global (with the keyword static). Defining them as static basically means they aren't freed after the function completes its execution. So next time you call the function their value is what you last set it to be in the function.

To define them as super global, you'd define the variables outside of the function (at the very top of your script) with the keyword global like this:

global runVM := false
global linux := false
Pause::vmStart()
...

This would mean any scope anywhere that tried to reference a variable by that name would use your super global variable. This is bad practice and can be dangerous to do, especially if you use external libraries. Wouldn't be too hard to accidentally break something.

Of course when you have a little script like that, is makes no difference whatsoever what method you use. Even I confess to sometimes using super global on my personal scripts, just because it's quite convenient to not have to worry about scopes.

If you'd like to hear my recommendation, I'd say go for static variables.
It's pretty much exactly intended for what you're doing here.

Here's your finished product (with some miscellaneous changes) in case I didn't explain something well enough:

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
}

这篇关于我的AutoHotKey脚本如何相应地启动批处理脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆