wmic DiskDrive 其中 (MediaType!='可移动媒体') 在设置 SetLocal EnableDelayedExtensions 时获取模型返回意外值

问题描述 投票:0回答:2

例如这段代码

wmic DiskDrive where (MediaType!='Removable media') get model

返回系统中除可移动设备之外的所有存储设备

但是这段代码

SetLocal EnableelaysedExtensions
wmic DiskDrive where (MediaType!='Removable media') get model

返回完全相反的结果 - 系统中仅可移动设备。

有什么办法可以解决吗? 我需要在脚本中使用 SetLocal 指令用于其他目的,所以我无法删除它。

cmd wmic
2个回答
0
投票

命令的正确语法应该是:

%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

0
投票

命令行

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 /?

另请参阅:Windows 命令解释器 (CMD.EXE) 如何解析脚本?

© www.soinside.com 2019 - 2024. All rights reserved.