AHK/AutoHotkey测试:
shell := ComObjCreate("WScript.Shell") ExecThenOutput(command){ global shell exec := shell.Exec(ComSpec " /C " . command) FileAppend, % exec.StdOut.ReadAll() "`n",* } ExecThenOutput("net session 2>&1") ; 发生系统错误 5。拒绝访问。 ExecThenOutput("echo %errorlevel%") ; 0 ExecThenOutput("net session 2>&1 && echo %errorlevel%") ; 发生系统错误 5。拒绝访问。 ExecThenOutput("net session 2>&1 `; echo %errorlevel%") ; 此命令的语法是:.. ExecThenOutput("net session 2>&1 || echo %errorlevel%") ; 发生系统错误 5。拒绝访问。 ; 0 ExecThenOutput("chcp") ; 活动代码页: 936 ExecThenOutput("net session 2>&1 | chcp") ; 活动代码页: 936 ExecThenOutput("net session 2>&1 | echo %errorlevel%") ; 0
更正见后。
使用管道符"|"连接的两命令,后一个命令中的变量(如下的errorlevel)的(运行时)值独立于先于前一个命令,或者说,前一个命令不影响后一个命令中的变量,或者说,变量求值先于(前、后)命令,或者说,且变量求值的运行时先于管道命令,管道运算先于命令。
即运算优先级/顺序:变量求值>管道运算>命令。
C:WINDOWSsystem32>net session >nul 2>&1 | %errorlevel% '0' 不是内部或外部命令,也不是可运行的程序 或批处理文件。 C:WINDOWSsystem32>net session >nul 2>&1 | %errorlevel% '9009' 不是内部或外部命令,也不是可运行的程序 或批处理文件。 C:WINDOWSsystem32>net session >nul 2>&1 | echo %errorlevel% 9009 C:WINDOWSsystem32>net session >nul 2>&1 | echo %errorlevel% 0
C:UsersRobertL>net session >nul 2>&1
C:UsersRobertL>echo %errorlevel%
2
但以上即便ExecThenOutput("net session 2>&1")后ExecThenOutput("echo %errorlevel%"),(echo)仍显示0(不同于命令行下),如同两次执行彼此无关、不在一个环境中。
验证(命令行下,AHK的WScript.Shell不同?)
>set x=1 & echo %x% >set x=2 & echo %x% 1 >set x=3 & echo %x% 2
尝试: shell当中多个命令放在一起执行的几个方法_huangzx3的博客-CSDN博客
非管理员下: C:UsersRobertL>net session >nul 2>&1 ; echo %errorlevel% C:UsersRobertL>net session >nul 2>&1 && echo %errorlevel% C:UsersRobertL>net session >nul 2>&1 || echo %errorlevel% 2 (实为前一个命令的errorlevel)
管理员下: C:WINDOWSsystem32>net session >nul 2>&1 ; echo %errorlevel% C:WINDOWSsystem32>net session >nul 2>&1 || echo %errorlevel% C:WINDOWSsystem32>net session >nul 2>&1 && echo %errorlevel% 0 (实为前一个命令的errorlevel)
类似的,有:shell命令串联起来执行的几种方法_hoooo1的博客-CSDN博客_shell拼接命令并执行
分号";"连接总是无效(如同没有分号后的内容)(见下)
类似的,有:如何在 Windows CMD 中的一行中运行两个命令? - 协慌网 (routinepanic.com)
尝试使用&,总是有效(如同上面的";“),但实为前一个命令的errorlevel。
尝试^T,无效(如同没有其后的内容)。
尝试:如何通过WScript.Shell连续调用命令行-CSDN论坛 (googleusercontent.com)
StandardInput.WriteLine(..)。
参见:关于vba:在WScript.Shell对象中调用Run时无法识别环境变量 | 码农家园 (codenong.com)
推荐,但属于搬运、翻译。
相关/扩展:关于cmd:是否有命令从Windows中的命令提示符刷新环境变量? | 码农家园 (codenong.com)
搜索:命令行 命令 连续 串联 WScript.Shell 环境变量 errorlevel - Google 搜索
WScript.Shell exec errorlevel - Google 搜索
参考:windows - Get errorlevel in bat from vbscript - Stack Overflow
WScript.Quit
参考:windows - Getting the return value from a cmd /c command in VBScript - Stack Overflow
/V:ON 使用 ! 作为分隔符启用延迟的环境变量
扩展。例如,/V:ON 会允许 !var! 在执行时
扩展变量 var。var 语法会在输入时
扩展变量,这与在一个 FOR
循环内不同。如果延迟环境变量扩展被启用,
惊叹号字符可在执行时间被用来
代替一个环境变量的数值。
Start the
cmd
instance with delayed expansion enabled (/v
) and exit thecmd
instance with theerrorlevel
set by the previous command.Delayed expansion is needed because the
cmd
parser replaces all%var%
read operations with the value inside the variables during the line/block parse phase. Without delayed expansion (%errorlevel%
), the value to be returned by theexit
command will be retrived before starting to execute the command. With delayed expansion (!errorlevel!
) the value will be retrieved when theexit
command is executed, after thecommandGoesHere
has ended.
测试
echo %x% !x! & set x=2 & echo %x% !x! 1 1 1 2
使用/V选项并搭配!分隔符后的测试,正常:
shell := ComObjCreate("WScript.Shell") ExecThenOutput(command){ global shell exec := shell.Exec(ComSpec " /V:ON /C " . command) FileAppend, % exec.StdOut.ReadAll() "`n",* } ExecThenOutput("net session >nul 2>&1 || echo !errorlevel!") ; when not Administrator Mode 2 ; when Administrator Mode 0
参考:scripting - VBScript getting results from Shell - Stack Overflow
exec.Status/ExitCode / exec.StdErr/StdOut
WScript.StdOut.Write / WScript.Echo