首页 > 解决方案 > 从批处理文件中调用 FOR 表达式中的“ver”会冻结 Windows 10 中的 cmd

问题描述

我正在尝试从批处理文件中检查操作系统版本,但遇到了以下问题。

线

FOR /F "tokens=*" %%i IN ('ver') DO (SET var=%%i)

从批处理文件执行时将冻结 cmd 而命令ver本身(在同一个批处理文件中)执行没有问题。(ver具有以下输出。)

Microsoft Windows [Version 10.0.18362.356]

表达中可能有什么问题?

标签: windowsbatch-filecmdwindows-10

解决方案


正如您在问题下方的评论中提到的那样,明显的冻结是由于您已将 cmd 语句设置为通过 cmd 的AutoRun注册表设置执行:[HKEY_LOCAL_MACHINE/HKEY_CURRENT_USER]\Software\Microsoft\Command Processor\AutoRun

for /F用于捕获另一个命令/程序的输出时,cmd将调用 的隐式实例来执行forIN 子句中引用的命令/程序。

当 cmd 的AutoRun注册表设置中有一个条目时,该隐式cmd实例将依次执行AutoRun命令,并且在您的情况下,该AutoRun命令将cmd通过该for /F命令执行另一个实例。您会看到它的发展方向:cmd将启动无限的嵌套 s 链,直到耗尽系统资源。

为避免陷入无限循环,您需要防止语句执行多次

这是一种编写为批处理文件的方法:

:: This batch file can be safely executed through cmd's Autorun

@echo off
if not defined WinVer (
    set "WinVer=AutorunGuard"
    for /F "tokens=1* delims=[" %%A in ('ver') do (
        for /F "tokens=2 delims=] " %%V in ("%%B") do set "WinVer=%%V"
    )
)

我还扩展了提取 windows 版本的方法,只包含版本号,而不是返回的整个版本字符串ver
它可以用来提取从 Windows 2000 到 Windows 10 的 windows 版本的版本号

如果您不想使用批处理文件,并且更喜欢将语句海峡放入AutoRun注册表设置,则可以使用此单行代码:

@if not defined WinVer set "WinVer=AutorunGuard" & for /F "tokens=1* delims=[" %A in ('ver') do @for /F "tokens=2 delims=] " %V in ("%B") do @set "WinVer=%V"

推荐阅读