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 7
和Windows 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 - 处理批处理文件中带有空格的文件夹名称的主要内容,如果未能解决你的问题,请参考以下文章
Windows 10 1803 OS升级与Citrix VDA 7.15 LTSR兼容性问题
Windows 7和Windows Server 2008 有啥区别
Delphi Tokyo 10.2 Windows 7上的TDSRestConnection DataSnap连接