【问题标题】:NSIS Runtime CMD with spaces in path and parameterNSIS 运行时 CMD,路径和参数中有空格
【发布时间】:2018-06-21 09:53:36
【问题描述】:

我有一个 Windows .bat 脚本,需要在运行时从 NSIS 安装程序运行。

脚本调用如下:

   ; Debug Messages to check values set correctly
   MessageBox MB_OK "Script ${INSTDIR}\script\settingsLocation.bat"
   MessageBox MB_OK "INSTDIR $INSTDIR "
   MessageBox MB_OK "SettingsDirType $SettingsDirType"
   MessageBox MB_OK "SettingsDirName $SettingsDirName"
   MessageBox MB_OK "Calling script ${INSTDIR}\script\settingsLocation.bat $INSTDIR $SettingsDirType $SettingsDirName"

   nsExec::ExecToStack 'CMD.exe /C ""${INSTDIR}\script\settingsLocation.bat"" ""${INSTDIR}"" $SettingsDirType $SettingsDirName'

   ; Check result status and output
   Pop $0
   MessageBox mb_ok "CMDout 0=$0"
   Pop $0
   MessageBox mb_ok "CMD Out 1=$0"

使用上面的,变量$INSTDIR没有展开,所以命令找不到脚本也就不足为奇了。

$INSDIR"C:\Program Files (x86)\Prog Name"(三个空格)。

但我使用以下内容(将"" 替换为"):

nsExec::ExecToStack 'CMD.exe /C "${INSTDIR}\script\settingsLocation.bat" "${INSTDIR}" $SettingsDirType $SettingsDirName'

我明白了:

'C:\Program' is not recognized as an internal command, operable program or batch file.

显然,我正处于非扩展和完全扩展忽略引号的 2 个凳子之间。

我怎样才能保留引号,以便命令像手动键入一样运行,如下所示:

"C:\Program Files (x86)\Prog Name\script\settingsLocation.bat" "C:\Program Files (x86)\Prog Name" DTYPE DNAME

更新 1(根据安德斯的回复):

我尝试了以下模组:

   nsExec::ExecToStack 'CMD.exe /C "$INSTDIR\script\settingsLocation.bat" "$INSTDIR" $SettingsDirType $SettingsDirName'

即将${INSTDIR}更改为$INSTDIR

这给出了:

'C:\Program' is not recognized as a internal or external command

更新 2

尝试转义内部双引号,如下所示:

   nsExec::ExecToStack 'CMD.exe /C \"$INSTDIR\script\settingsLocation.bat\" \"$INSTDIR\" $SettingsDirType $SettingsDirName'

但这给了:

'\"C:\Program Files\....\" is not a recognised as an internal; or external command,

更新 3(已解决!!)

在下面 Anders 的进一步帮助下,添加 if 1==1 位终于让它工作了:

   nsExec::ExecToStack 'CMD.exe /C if 1==1 "$INSTDIR\script\settingsLocation.bat" "$INSTDIR" $SettingsDirType $SettingsDirName'

【问题讨论】:

    标签: cmd whitespace nsis pathname


    【解决方案1】:

    Instdir 是一个变量,而不是一个定义,所以你必须使用$InstDir,而不是${InstDir}

    CMD.exe 具有疯狂的引号处理功能,有时会删除您的引号,但有一些解决方法:

    nsExec::ExecToStack 'CMD.exe /C if 1==1 "c:\path with spaces\app.exe" param1 "par am 2"'
    

    【讨论】:

    • 谢谢。我改为nsExec::ExecToStack 'CMD.exe /C "$INSTDIR\script\settingsLocation.bat" "$INSTDIR" $SettingsDirType $SettingsDirName'。但仍然得到'C:\Program' is not recognised as a internal or external command
    • “'C:\Program' 未被识别为内部或外部命令”是一个引用问题。
    • 谢谢@Anders,if 1==1救了我。 cmd.exe 的引号处理很疯狂。
    • 有没有人碰巧知道这种引用行为记录在哪里?我认为我在相当高的层次上理解它,它强制对引号进行字面解释,以防止与可能从此处调用的其他命令(例如 PowerShell)的要求混淆。确切地知道这个概念被称为什么以及为什么 Windows Batch 会这样做,我会感到更自在。
    • @daniel 我认为是 cmd.exe /?解释了其中一些。 if 只是使它不以引号开头和结尾,并且禁用了疯狂的行为。
    猜你喜欢
    • 2020-06-18
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2017-06-18
    • 1970-01-01
    • 2017-05-07
    • 2019-04-26
    相关资源
    最近更新 更多