例如这段代码
wmic DiskDrive where (MediaType!='Removable media') get model
返回系统中除可移动设备之外的所有存储设备
但是这段代码
SetLocal EnableelaysedExtensions
wmic DiskDrive where (MediaType!='Removable media') get model
返回完全相反的结果 - 系统中仅可移动设备。
有什么办法可以解决吗? 我需要在脚本中使用 SetLocal 指令用于其他目的,所以我无法删除它。
命令的正确语法应该是:
%SystemRoot%\System32\wbem\WMIC.exe DiskDrive Where "MediaType != 'Removable media'" Get Model
但是,当启用延迟扩展时,
!
字符具有特殊含义,在这种情况下将被忽略。
最简单的解决方法是使用
!=
运算符的替代方案。如果您查看可用的 WQL 运算符,您应该注意到您可以改为使用,<>
:
%SystemRoot%\System32\wbem\WMIC.exe DiskDrive Where "MediaType <> 'Removable media'" Get Model
命令行
SetLocal EnableelaysedExtensions
导致错误消息:
SETLOCAL 命令的参数无效
命令SETLOCAL支持四个不同的参数,因为可以通过在打开的
命令提示符窗口中运行
setlocal /?
来读取它:
我想想要的代码是这样的:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "ModelCount=0"
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe DiskDrive where (MediaType^^!^="Removable media"^) GET Model /VALUE 2^>nul') do (
set /A ModelCount+=1
set "Model!ModelCount!=%%I"
)
set Model
pause
endlocal
命令 FOR 在这种情况下在后台运行,Windows 安装到
C:\Windows
:
C:\Windows\System32\cmd.exe /c C:\Windows\System32\wbem\wmic.exe DiskDrive where (MediaType!="Removable media") GET Model /VALUE 2>nul
WMIC 的输出采用 UTF-16 Little Endian (LE) 和字节顺序标记 (BOM) 进行 Unicode 编码,并由 FOR 处理。
在这种情况下,必须使用两个
!
转义感叹号 ^
,因为启用 延迟扩展 会被解释为文字字符,而不是延迟扩展环境变量引用的开头。由于启用了延迟扩展,Windows 命令处理器会解析命令行两次。因此,在第一次解析时 ^^!
变为^!
,在第二次解析时,插入符号现在被解释为解释标记的转义字符,因此,仅将 !
传递给分别在后台启动的 cmd.exe
wmic.exe
在后台执行。
=
子句中的等号where
也必须使用^
转义才能被解释为文字字符,否则cmd.exe
处理批处理文件会将其解释为参数分隔符并用普通空格替换等号会使 where
子句无效的字符。
)
也必须仅用一个 ^
进行转义才能被解释为文字字符,而不是命令 FOR 集的结尾。 where
子句的两个圆括号并不是真正必要的。所以也可以使用:
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe DiskDrive where MediaType^^!^="Removable media" GET Model /VALUE 2^>nul') do (
阅读有关 使用命令重定向运算符的 Microsoft 文档,了解
2>nul
的说明。重定向运算符 >
必须在 FOR命令行上使用脱字符号
^
进行转义,以便在 Windows 命令解释器在执行命令 FOR(执行嵌入的 wmic
命令行)之前处理此命令行时将其解释为文字字符使用在后台启动的单独命令进程。
请注意,分配给循环变量
I
的磁盘驱动器型号字符串包含一个或多个感叹号,将被错误地分配给环境变量,因为启用了延迟扩展导致解释中导致第二次解析命令行set "Model!ModelCount!=%%I"
分配给循环变量 I
的字符串中的感叹号作为延迟扩展环境变量引用的开始/结束。
请进一步注意,由于使用 FOR /F 选项
tokens=2 delims==
,字符串中带有等号的磁盘驱动器型号字符串也将无法正确处理。但我从未见过型号名称中带有 =
的磁盘驱动器。这应该永远不是问题。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
echo /?
endlocal /?
for /?
pause /?
set /?
setlocal /?
wmic /?
wmic diskdrive /?
wmic diskdrive get /?