【问题标题】:What could be the reason for error message "Invalid XSL format (or) file name" output by WMIC on retrieving day of week?WMIC 在检索星期几时输出错误消息“无效的 XSL 格式(或)文件名”的原因可能是什么?
【发布时间】:2016-07-18 09:45:35
【问题描述】:

操作系统:Microsoft Windows Server 2008 R2
Windows\SYSWOW64 中的相同 XSL 文件存在于目录 Windows\System32 中。

批处理命令:

for /F "skip=2 tokens=2-4 delims=," %A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Format:csv') do set DAYNUMBER=%A

德语错误:

Ungültiges XSL 格式(oder)日期名称。

英文错误:

无效的 XSL 格式(或)文件名。

评论:这是一个没有 Windows 更新的生产服务器。

WMIC 在检索星期几时输出此错误消息的原因可能是什么?

【问题讨论】:

    标签: batch-file wmic


    【解决方案1】:

    Windows 7 和 Windows Server 2008 R2 的wmic 按照指定的格式搜索*.xsl 文件,如csv 目录第一

    %SystemRoot%\System32\wbem

    但此目录不再包含 Windows 7 或 Windows Server 2008 R2 上的 *.xsl 文件。即使这个目录下有合适的*.xsl文件,它也会首先被wmic忽略。

    下一个wmic 在目录中搜索适当的*.xsl 文件

    %SystemRoot%\System32\wbem\语言国家

    根据操作系统的语言和国家。例如,如果使用英文 Windows 7 并使用 /format:csv,则 wmic 搜索并首先找到

    %SystemRoot%\System32\wbem\en-US\csv.xsl
    

    但如果 Format 在 Windows Control Panel 标签 Formats 上的 Region and Language 设置中定义为设置为与操作系统语言和国家/地区不同的语言和国家/地区,例如 德语(奥地利)wmic 会忽略在操作系统语言和国家/地区子目录中找到的 csv.xsl,并在接下来搜索 @987654336 @ 指定格式语言和国家/地区子目录中的文件,用于此示例

    %SystemRoot%\System32\wbem\de-AT\csv.xsl
    

    但即使使用德语 Windows 7 或德语 Windows Server 2008 R2 也没有这样的目录,因为操作系统仅在 de-DE 中可用。

    最后wmic在目录中再次搜索

    %SystemRoot%\System32\wbem

    用于在 Windows XP 上找到的 *.xsl 文件。但在 Windows 7 和 Windows Server 2008 R2 上,此目录不再包含 *.xsl 文件,因为现在依赖于语言。

    这个问题至少有4个解决方案:

    1. 区域和语言设置中格式选项卡上的格式设置为与操作系统相同的语言和国家/地区。

      这意味着在奥地利使用的英语 Windows 7 上将 Format德语(奥地利) 更改为 英语(美国)。或者在奥地利使用的德语 Windows Server 2008 R2 上将 FormatGerman (Austria) 更改为 German (Germany)

      注意:日期/时间格式也会发生变化。 German (Austria)German (Germany) 之间甚至存在差异,尽管它们不像 Jänner 用于奥地利与 Januar 用于德国,采用长日期格式。在奥地利或德国使用的 Windows 计算机上使用英语(美国)确实不可取。

    2. 操作系统的现有 language-country 子目录中的 *.xls 文件以管理员权限复制到 %SystemRoot%\System32\wbem,对于 Windows x64 和 32 位 @ 64 位 wmic Windows x86 上的 987654345@ 以及 Windows x64 上的 32 位 %SystemRoot%\SysWOW64\wbem %SystemRoot%\SysWOW64\wbem

      注意:不建议使用此解决方案,因为将来可能会发生 Windows 更新更新一个或多个 *.xsl 文件,从而导致 wbem 目录中包含较旧的 *.xsl 文件更新后仍在使用。

      对于将英语 Windows 7 和德语(奥地利)设置为格式的示例,wmic 的搜索行为如下:
      wmic 首先在 %SystemRoot%\System32\wbem 中找到 csv.xsl 并首先忽略它。接下来它会在%SystemRoot%\System32\wbem\en-US 中找到该文件并忽略该文件。然后它在%SystemRoot%\System32\wbem\de-AT 中搜索文件,但是这个目录根本不存在。最后它再次找到%SystemRoot%\System32\wbem 中的文件并现在读取它。

    3. 格式用双引号括起来的完整路径和文件名指定。那么wmic 一定不要四处寻找文件。

      这意味着要使用英文版 Windows 7 或 Windows Server 2008 R2

      %SystemRoot%\System32\wbem\wmic.exe Path Win32_LocalTime Get DayOfWeek /Format:"%SystemRoot%\System32\wbem\en-US\csv.xsl"
      

      对于德语 Windows 7 或 Windows Server 2008 R2 使用

      %SystemRoot%\System32\wbem\wmic.exe Path Win32_LocalTime Get DayOfWeek /Format:"%SystemRoot%\System32\wbem\de-DE\csv.xsl"
      

      注意:文件名两边的双引号很重要,否则执行可能会失败并显示错误消息

      无效命令。

      我不知道为什么完整文件名周围没有双引号的格式规范会失败,尽管完整文件名不包含空格。可能是wmic的命令行参数解析错误。

    4. 当前目录设置为真正存在的目录wbem中的language-country子目录,格式用文件名和文件扩展名指定,但没有路径。

      德语 Windows Server 2008 R2 示例:

      cd /D "%SystemRoot%\System32\wbem\de-DE"
      ..\wmic.exe Path Win32_LocalTime Get DayOfWeek /Format:csv.xsl
      

      文件扩展名很重要,否则文件将再次找不到。

    我使用来自 Sysinternals (Microsoft) 的免费工具 Process Monitor 发现了文件搜索行为。

    但是对于这个特定任务有一个独立于格式的解决方案,根本不使用 CSV 格式。


    绝对不需要在命令行中使用/Format:csv 来获取星期几,0 代表星期日,1 代表星期一,2 代表星期二,...,6 代表星期六。

    在批处理文件中使用:

    @echo off
    for /F "skip=1" %%W in ('%SystemRoot%\System32\wbem\wmic.exe path win32_localtime get DayOfWeek') do (
        set "DAYNUMBER=%%W"
        goto ProcessWeekDay
    )
    :ProcessWeekDay
    echo Day of week is: %DAYNUMBER%
    

    要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

    • for /?
    • goto /?
    • set /?
    • wmic path win32_localtime get /?

    在命令提示符窗口wmic path win32_localtime get DayOfWeek 中运行,您可以看到该命令输出了哪些行:

    DayOfWeek  
    1          
     
    

    现在更清楚为什么命令 FOR 应该跳过第一行并将第二行中的值分配给环境变量。注意:DayOfWeek 和值1 后面有空格。

    看不到的是 WMIC 以 Unicode 编码 UTF-16 Little Endian 和 BOM(字节顺序标记)输出 3 行。命令 FOR 在解析 UTF-16 编码输出时存在一些问题,并将第三行错误的回车解释为从空行读取的字符串。因此,必须在将第二行中的星期几的值分配给环境变量后退出循环,以避免在刚刚设置后立即清除环境变量。

    DavidPostill 建议的另一种方法是使用 Windows 标准控制台应用程序 FINDSTR 过滤掉 WMIC 的 Unicode 输出底部的空白行。

    @echo off
    for /F "skip=1" %%W in ('%SystemRoot%\System32\wbem\wmic.exe path win32_localtime get DayOfWeek ^| %SystemRoot%\System32\findstr.exe /R /V "^$"') do set "DAYNUMBER=%%W"
    echo Day of week is: %DAYNUMBER%
    

    另一种变体,它使用 FINDSTRFOR 处理,只是以 0-6 范围内的数字开头的行。

    @echo off
    for /F %%W in ('%SystemRoot%\System32\wbem\wmic.exe path win32_localtime get DayOfWeek ^| %SystemRoot%\System32\findstr.exe /R "^[0-6]"') do set "DAYNUMBER=%%W"
    echo Day of week is: %DAYNUMBER%
    

    带有值的行还有 10 个尾随空格,这就是为什么正则表达式 ^[0-6]$ 不起作用,但 ^[0-6].*$ 或更简单的 ^[0-6] 起作用的原因。
    FOR 删除那些尾随空格,因为默认分隔符是空格字符和将行拆分为标记时的水平制表符。

    工作也是:

    @echo off
    for /F %%W in ('%SystemRoot%\System32\wbem\wmic.exe path win32_localtime get DayOfWeek ^| %SystemRoot%\System32\more.com +1') do set "DAYNUMBER=%%W"
    echo Day of week is: %DAYNUMBER%
    

    标准 Windows 控制台应用程序 MORE 用于将 Unicode 输出(每个字符 2 个字节)转换为 OEM(每个字符 1 个字节),MORE 已经跳过了第一行>.

    好吧,实际上 WMIC 仅输出 2 行,而第三个空白行是 Windows 命令解释器将编码不佳的 Unicode 转换为 OEM 的结果。

    【讨论】:

    • 你也可以通过管道将wmic 输出到findstr 以删除空行:'%SystemRoot%\System32\wbem\wmic.exe path win32_localtime get DayOfWeek ^| findstr /r /v "^$"' 然后你不需要goto 和标签。
    • @DavidPostill 用findstr 过滤空行确实是一个非常好的主意。它使这个任务的代码有点慢。但是如果输出行数不固定的话,用findstr过滤输出wmic肯定比我之前用的好(将wmic输出重定向到文件,type文件在for内,删除后的文件循环)。非常感谢这个非常有用的过滤方法。顺便说一句:在我用作此答案模板的批处理文件中,我有if %%W == 6 goto WeeklyCleanup,因此循环后没有额外的标签。
    • 不客气 :) 我不担心这么短的批处理文件的速度,所以我总是使用 wmicfindstr
    【解决方案2】:

    解决办法是:

    地区和语言设置: 德/厄斯特赖希 变成 德/德国

    第二个解决方案是定义 csv 文件的确切路径 WMIC 路径 Win32_LocalTime 获取 DayOfWeek /Format:%SystemRoot%\System32\wbem\de-de\csv.xls

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多