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

Cmd 设置SetLocal EnableDelayedExtensions时,wmic DiskDrive其中(MediaType!=';可移动媒体';)获取模型返回意外值,cmd,wmic,Cmd,Wmic,例如,此代码 wmic DiskDrive where (MediaType!='Removable media') get model SetLocal EnableelaysedExtensions wmic DiskDrive where (MediaType!='Removable media') get model 返回系统中除可移动设备以外的所有存储设备 但是这个代码 wmic DiskDrive where (MediaType!='Removable media') get

例如,此代码

wmic DiskDrive where (MediaType!='Removable media') get model
SetLocal EnableelaysedExtensions
wmic DiskDrive where (MediaType!='Removable media') get model
返回系统中除可移动设备以外的所有存储设备

但是这个代码

wmic DiskDrive where (MediaType!='Removable media') get model
SetLocal EnableelaysedExtensions
wmic DiskDrive where (MediaType!='Removable media') get model
返回完全相反的结果-系统中只有可移动设备

有什么办法可以解决吗?
出于其他目的,我需要脚本中的SetLocal指令,因此无法将其删除。

命令行
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的输出采用带字节顺序标记(BOM)的UTF-16小尾端(LE)进行Unicode编码,由FOR处理

感叹号
^
对code>进行转义,因为允许将其解释为文字字符,而不是延迟扩展的环境变量引用的开头。由于启用了延迟扩展,Windows命令处理器将对命令行进行两次分析。由于这个原因,在第一次解析
^^变成了
^第二次解析时,插入符号字符现在被解释为解释标记的转义字符,因此只需
被传递给分别在后台启动的
cmd.exe
wmic.exe
在后台执行

where
子句中的等号
=
也必须用
^
转义,以解释为文字字符,否则
cmd.exe
处理批处理文件会将其解释为参数分隔符,并用普通空格字符替换等号,从而生成
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文档,以了解有关nul的说明。当Windows命令解释器在执行
的命令之前处理该命令行时,重定向操作符
必须在上用插入符号
^
转义,以便命令行被解释为文字字符,该命令行以单独的方式执行嵌入的wmic命令行命令进程在后台启动

请注意,分配给包含一个或多个感叹号的循环变量
I
的磁盘驱动器型号字符串将被错误地分配给环境变量,因为第二次解析命令行
set“model!ModelCount!=%%I”
由于启用延迟扩展,导致将分配给循环变量
I
的字符串中的感叹号解释为延迟扩展环境变量引用的开始/结束

请进一步注意,字符串中带有等号的磁盘驱动器型号字符串也将不正确处理,因为使用了FOR/F选项
tokens=2 delims==
。但我从未见过型号名称中带有
=
的磁盘驱动器。所以这应该永远不会是一个问题

要了解所使用的命令及其工作方式,请打开一个窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面

  • echo/?
  • endlocal/?
  • 获取/?
  • 暂停/?
  • 设置/?
  • setlocal/?
  • wmic/?
  • wmic diskdrive/?
  • wmic diskdrive获取/?

另请参见:

命令的正确语法应为:

%SystemRoot%\System32\wbem\WMIC.exe DiskDrive,其中“MediaType!=‘可移动媒体’”获取模型
但是,当启用延迟扩展时,
字符具有特殊含义,在本例中忽略

最简单的修复方法是使用
的替代方案=操作员。如果您查看可用的,您应该注意,您可以改为使用,

%SystemRoot%\System32\wbem\WMIC.exe DiskDrive,其中“MediaType‘Removable media’”获取模型

SetLocal EnableelaysedExtensions
肯定会给您一个语法错误,并且不会影响感叹号,因为它肯定不会启用
wmic DiskDrive where(MediaType^^!=“Removable media”)获取模型
alive one,我注意到,您已登录此网站返回,但未回复上述评论或提供官方答案的人。请查看以了解在此场景中您可以选择哪些选项,因为没有可接受答案的问题不会被此网站视为已回答。