Windows 7 与 Windows 10 - 处理批处理文件中带有空格的文件夹名称

Posted

技术标签:

【中文标题】Windows 7 与 Windows 10 - 处理批处理文件中带有空格的文件夹名称【英文标题】:Windows 7 vs Windows 10 - Handling folder names with spaces in batch files 【发布时间】:2018-09-24 07:43:13 【问题描述】:

我正在尝试创建一个必须在Windows 7Windows 10 上运行的批处理脚本。但是,每个处理带有空格的文件夹名称的方式似乎有所不同,我必须以不同的方式转义它们。

特别是在Windows 7 上,我成功使用了以下命令:

start cmd.exe /k "%OpenOCD_bin_Path%\openocd.exe -f %OpenOCD_bin_Path%\..\scripts\interface\ftdi\SuperDongle.cfg -f %OpenOCD_bin_Path%\..\scripts\target\nrf52.cfg"

OpenOCD_bin_Path 包含一个文件夹,其中包含空格;它引用的完整路径是:

C:\Users\Rafael\AppData\Roaming\GNU MCU Eclipse\OpenOCD\0.10.0-7-20180123-1217\bin

但是,在Windows 10 上,同一行失败并显示以下错误:

'C:\Users\Rafael\AppData\Roaming\GNU' 不是内部或外部命令、可运行程序或批处理文件。

如果我将命令更改为:

start cmd.exe /k ""%OpenOCD_bin_Path%"\openocd.exe -f "%OpenOCD_bin_Path%"\..\scripts\interface\ftdi\SuperDongle.cfg -f "%OpenOCD_bin_Path%"\..\scripts\target\nrf52.cfg"

成功了。

相反,如果我在 Windows 7 上运行该命令,我会收到以下错误:

'""C:\Users\Rafael\AppData\Roaming\GNU' 不是内部或外部命令、可运行程序或批处理文件。

注意这个版本前面额外的""

TLDR;有没有一种方法可以在两个系统上都进行这项工作,而无需使用开关来检测正在运行的操作系统?

【问题讨论】:

如果你使用Start/D选项会发生什么?或者也许首先使用CD /D 将当前工作目录设置为最深的公共父级,然后使用<pathto>\openocd.exe -f interface\ftdi\SuperDongle.cfg -f target\nrf52.cfg。顺便说一句,C:\Users\Rafael\AppData\Roaming 可以替换为 %AppData% 【参考方案1】:

cmd.exe 很傻,它会从命令中删除开始和结束的引号,但是有一个技巧可以打败它:

start cmd.exe /k if 1==1 "%OpenOCD_bin_Path%\openocd.exe" -f "%OpenOCD_bin_Path%\..\scripts\interface\ftdi\SuperDongle.cfg" -f "%OpenOCD_bin_Path%\..\scripts\target\nrf52.cfg"

无论如何,从start 调用 cmd.exe 毫无意义,只需使用start

start "" "%OpenOCD_bin_Path%\openocd.exe" -f "%OpenOCD_bin_Path%\..\scripts\interface\ftdi\SuperDongle.cfg" -f "%OpenOCD_bin_Path%\..\scripts\target\nrf52.cfg"

重要的是%OpenOCD_bin_Path% 在所有系统上的引号都相同。您通常不会引用环境中设置的路径,因为在需要时很难再次删除引号。

你可以去掉引号,但理想情况下你应该避免处理批处理文件中的字符串操作,因为转义问题。

这是一个尝试处理这两种情况的示例:

@echo off
goto run_tests

:stripquotes
FOR /F "tokens=1,*" %%A IN ('echo.%*') DO set %%~A=%%~B
goto :EOF

:test
call :stripquotes mynewvar %*
echo DEBUG: mynewvar is now %mynewvar%
start "" "%mynewvar%\app.exe" "par am 1" param2 "par am 3"
goto :EOF


:run_tests
set OpenOCD_bin_Path=c:\foo bar\baz
call :test %OpenOCD_bin_Path%

set OpenOCD_bin_Path="c:\foo bar\baz"
call :test %OpenOCD_bin_Path%

【讨论】:

如果我做第一个,它在 Windows 10 中有效,但在 7 中无效(与最初的错误相同),第二个根本不起作用。它会创建一个弹出窗口,说“检查命令并重试”或其他内容,并打印整个(但正确取消引用)命令... 你确定 %OpenOCD_bin_Path% 在两个系统上是一样的吗? 这不一样,有趣的是。在 Windows 7 上,它有双引号,但在 Windows 10 上没有。通过“回声”访问。星期一我会再多说一些,但据我所知,它们是使用完全相同的命令“setx -m”创建的,该命令之前是从另一个批处理文件运行的。 它不应该有引号。带有引号的不完整路径很难处理。我将使用去掉引号的版本更新我的代码... 我能够调整您的报价处理脚本。到目前为止,它可以在两个平台上运行...一旦我进行了更全面的测试,很快就会更新。【参考方案2】:

使用我在评论中提供的任何一个想法都应该绕过空格。

使用CD /D

@Echo Off
Set "OpenOCD_bin_Path=%AppData%\GNU MCU Eclipse\OpenOCD\0.10.0-7-20180123-1217\bin"
CD /D "%OpenOCD_bin_Path%\..\scripts" 2>Nul || Exit / B
Start "" Cmd /K "..\bin\openocd.exe -f interface\ftdi\SuperDongle.cfg -f target\nrf52.cfg"

或者你也可以在不明确启动cmd.exe的情况下尝试:

@Echo Off
Set "OpenOCD_bin_Path=%AppData%\GNU MCU Eclipse\OpenOCD\0.10.0-7-20180123-1217\bin"
CD /D "%OpenOCD_bin_Path%\..\scripts" 2>Nul || Exit / B
Start ..\bin\openocd.exe -f interface\ftdi\SuperDongle.cfg -f target\nrf52.cfg

使用Start /D

@Echo Off
Set "OpenOCD_bin_Path=%AppData%\GNU MCU Eclipse\OpenOCD\0.10.0-7-20180123-1217\bin"
Start "" /D "%OpenOCD_bin_Path%" Cmd /K "openocd.exe -f ..\scripts\interface\ftdi\SuperDongle.cfg -f ..\scripts\target\nrf52.cfg"

或者在没有明确启动cmd.exe的情况下再次:

@Echo Off
Set "OpenOCD_bin_Path=%AppData%\GNU MCU Eclipse\OpenOCD\0.10.0-7-20180123-1217\bin"
Start "" /D "%OpenOCD_bin_Path%" openocd.exe -f ..\scripts\interface\ftdi\SuperDongle.cfg -f ..\scripts\target\nrf52.cfg

【讨论】:

好的,前两个适用于 Windows 7 和 10,后两个仅适用于 Windows 10。 刚刚测试了完整的东西,它们都不能在我的应用程序中正常工作。这是因为存在于原始目录中的脚本引用的文件更多。如果我使用 CD 调用该命令或在 %OpenOCD_bin_Path% 中启动它,这是一个不同的环境,因此找不到这些文件。它确实适用于我完全从调用目录启动命令的版本,所以除非我更改脚本的其余部分(这会引发更多问题),否则我实际上确实需要正确取消引用实际命令中的路径。

以上是关于Windows 7 与 Windows 10 - 处理批处理文件中带有空格的文件夹名称的主要内容,如果未能解决你的问题,请参考以下文章

ABplayer与windows 7 兼容问题?

Windows 10 1803 OS升级与Citrix VDA 7.15 LTSR兼容性问题

Windows 7和Windows Server 2008 有啥区别

Delphi Tokyo 10.2 Windows 7上的TDSRestConnection DataSnap连接

如何在不安装在 Windows 10 上的情况下知道与特定 XAMPP 版本关联的 php 版本?

CentOS 7与 Windows双系统丢失Windows启动项及默认启动项修改