萝卜L

导航

统计

管道 命令 %errorlevel! 环境变量 优先级 问题 随笔 CMD /V 延迟的环境变量

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:\WINDOWS\system32>net session >nul 2>&1 |  %errorlevel%
'0' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

C:\WINDOWS\system32>net session >nul 2>&1 |  %errorlevel%
'9009' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

C:\WINDOWS\system32>net session >nul 2>&1 | echo %errorlevel%
9009

C:\WINDOWS\system32>net session >nul 2>&1 | echo %errorlevel%
0
C:\Users\RobertL>net session >nul 2>&1
C:\Users\RobertL>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:\Users\RobertL>net session >nul 2>&1 ; echo %errorlevel%

C:\Users\RobertL>net session >nul 2>&1 && echo %errorlevel%

C:\Users\RobertL>net session >nul 2>&1 || echo %errorlevel%
2 (实为前一个命令的errorlevel)

管理员下:
C:\WINDOWS\system32>net session >nul 2>&1 ; echo %errorlevel%

C:\WINDOWS\system32>net session >nul 2>&1 || echo %errorlevel%

C:\WINDOWS\system32>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 the cmd instance with the errorlevel 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 the exit command will be retrived before starting to execute the command. With delayed expansion (!errorlevel!) the value will be retrieved when the exit command is executed, after the commandGoesHere 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

 

posted on   萝卜L  阅读(185)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示