【问题标题】:Batch file - IF EXISTS statement "The system cannot open the device or file specified."批处理文件 - IF EXISTS 语句“系统无法打开指定的设备或文件。”
【发布时间】:2018-08-09 22:58:15
【问题描述】:

我编写了一个批处理文件来卸载有故障的 WiFi 驱动程序(英特尔 ProSet 无线)并在笔记本电脑上设置适当的无线配置文件。此脚本旨在通过 Symantec Management Agent 远程运行。

代码首先运行组策略更新以下拉适当的 来自服务器的网络证书。然后代码检查是否安装了 WiFi 驱动程序。如果是,则脚本将其卸载。之后,无论哪种情况,它都会擦除当前的无线配置文件并调用另一个批处理文件来安装相应的无线配置文件。

我的问题是,当我运行脚本时,控制台会报告“系统无法打开指定的设备或文件”。软件卸载后将终止。 IF EXIST 语句检查是否存在软件文件之一。

通常,我可以再次运行相同的脚本,不会遇到 IF EXIST 的情况,因此批处理文件的其余部分将正常工作。

我在下面附上了我的代码——我是否正确使用了 IF EXIST?

gpupdate /force
IF EXIST "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" (

cd "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\"
start /wait setup.exe /uninstall

) 

TIMEOUT /T 3 /nobreak >nul
netsh wlan delete profile name=*
cd "C:\Wireless_Settings\"
Mobile_Devices_profile.bat

我研究了其他帖子,并且我相信我正确使用了该条件。我没有看到任何其他与我的情况相符的帖子。它总是正确检查是否满足条件,但是我不明白为什么在卸载软件后程序终止。我认为应该发生的就是不再满足这种情况,所以脚本继续。

【问题讨论】:

  • “系统无法打开指定的设备或文件。”错误似乎与.MSI/setup安装过程有关(谷歌建议例如暂停杀毒等.) stackoverflow.com/questions/32727996
  • 我同意@JosefZ,当我检查这些文件夹路径中是否存在文件时,我没有收到该消息。
  • 包缓存目录通常在卸载包时也会被删除。因此,将此目录设置为活动目录并不好。我建议将整个 IF 条件更改为:if exist "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" start "" /wait /D%SystemRoot%\System32 "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" /uninstall.

标签: windows batch-file file-exists


【解决方案1】:

可能的解决方案:(您的if 声明似乎是正确的)

cd 之前插入一个pushd 语句,在start 之后插入一个popd

这将确保您在 if 语句调用 setup.exe 后返回到原始目录


IF EXIST "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" (
PUSHD
cd "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\"
start /wait setup.exe /uninstall
POPD
) 

如果它有效,那很好。如果没有,很容易撤消。

当然 - 理论上,您可以将 cd 更改为 PUSHD。有很多路径。


IF EXIST "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" (
PUSHD "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\"
start /wait setup.exe /uninstall
POPD
) 

这应该可行。

现在这很有趣。我确定我之前使用过 pushd 没有参数。文档显示

存储当前目录以供 POPD 命令使用,然后 更改到指定目录。

PUSHD [路径 | ..]

选项参数缺失时不明确。

我还注意到,我的批处理开发目录中的 dir 列表现在列出了一个以 unicode 命名的文件,其中正方形之间有空格,而它过去不包含这些空格。也许有些东西已经悄悄地改变了……cmd 版本日期为 20170929

【讨论】:

  • pushd 声明而不是 cd?我建议CALL Mobile_Devices_profile.bat&PAUSE
  • @JosefZ No. pushd /cd .../start.../ popd 都在单独的行中,因为这样更容易反转。
  • @Magoo 我的想法和 JosefZ 一样。我将如何在这样的单独行上调用 pushd 和 cd ? pushd 不是或多或少地执行与 cd 相同的功能吗?另外,我确实尝试将其用作替代品,并收到了同样的错误。错误发生在 IF 语句的末尾。 TIMEOUT ....永远不会达到
  • 为什么 PUSHD 没有任何参数?如果既没有指定驱动器也没有指定路径PUSHD只显示以前的路径名列表...
  • pushd . 有效。它所做的只是记住当前目录。我不会那样用它。在脚本中移动当前工作目录通常是个坏主意。面对脚本失败,尤其是pushd/popd,它的组合并不好,它们只方便交互使用。使用完全限定或相对路径并使用start /d path ...
【解决方案2】:

Setup.exe 正在尝试从包缓存中删除该目录,该目录恰好是您当前的工作目录。这不是脚本生存的好方法。

@setlocal ENABLEEXTENSIONS
@rem @set prompt=$G

@set "_setupExe=C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe"

@gpupdate /force
@if exist "%_setupExe%" call %_setupExe% /uninstall

@TIMEOUT /T 3 /nobreak >nul
@netsh wlan delete profile name=*
@cd "C:\Wireless_Settings\"
@Mobile_Devices_profile.bat

我要补充一点,调试脚本很复杂,因为您有一个多行代码块。你应该不惜一切代价避免这些。如果您可以将所有子程序放在一行中,最好调用一个子程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 2017-08-01
    • 2021-06-23
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多