Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NSIS运行时CMD,路径和参数中带有空格_Cmd_Whitespace_Nsis_Pathname - Fatal编程技术网

NSIS运行时CMD,路径和参数中带有空格

NSIS运行时CMD,路径和参数中带有空格,cmd,whitespace,nsis,pathname,Cmd,Whitespace,Nsis,Pathname,我有一个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 $Setting

我有一个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"
"C:\Program Files (x86)\Prog Name\script\settingsLocation.bat" "C:\Program Files (x86)\Prog Name" DTYPE DNAME
   nsExec::ExecToStack 'CMD.exe /C \"$INSTDIR\script\settingsLocation.bat\" \"$INSTDIR\" $SettingsDirType $SettingsDirName'
使用上述方法,变量
$INSTDIR
不会展开,因此命令无法找到脚本也就不足为奇了

$INSDIR
“C:\ProgramFiles(x86)\Prog Name”
(三个空格)

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

我得到:

'C:\Program' is not recognized as an internal command, operable program or batch file.
很明显,我正处于非扩展和完全扩展的两个大便之间

如何保留引号,使命令可以像手动键入一样运行,如下所示:

   ; 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"
"C:\Program Files (x86)\Prog Name\script\settingsLocation.bat" "C:\Program Files (x86)\Prog Name" DTYPE DNAME
   nsExec::ExecToStack 'CMD.exe /C \"$INSTDIR\script\settingsLocation.bat\" \"$INSTDIR\" $SettingsDirType $SettingsDirName'
更新1(根据安德斯的回复):

我尝试了以下方法:

   nsExec::ExecToStack 'CMD.exe /C "$INSTDIR\script\settingsLocation.bat" "$INSTDIR" $SettingsDirType $SettingsDirName'
i、 e将
${INSTDIR}
更改为
$INSTDIR

这使得:

'C:\Program'未被识别为内部或外部命令

更新2

尝试按如下方式转义内部双引号:

   ; 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"
"C:\Program Files (x86)\Prog Name\script\settingsLocation.bat" "C:\Program Files (x86)\Prog Name" DTYPE DNAME
   nsExec::ExecToStack 'CMD.exe /C \"$INSTDIR\script\settingsLocation.bat\" \"$INSTDIR\" $SettingsDirType $SettingsDirName'
但这给了:

“\”C:\Program Files\..\”不是可识别为内部命令或外部命令的命令,

更新3(已解决!!)

在下面Anders的进一步帮助下,添加
if 1==1
位最终使其工作:

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

Instdir是一个变量,不是define,因此必须使用
$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”未被识别为内部或外部命令
“'C:\Program'未被识别为内部或外部命令。”“是一个引用问题。谢谢@Anders,
if 1==1
救了我。cmd.exe的报价处理是疯狂的。有人知道这种报价行为记录在哪里吗?我认为我在相当高的层次上理解了这一点,即它强制对引号进行文字解释,以防止与从此处调用的其他命令(例如PowerShell)的要求相混淆。知道这个概念的确切名称以及Windows批处理为什么会这样做,我会感到更舒服。@daniel我想cmd.exe/?解释了其中的一些。if只是使它不以引号开始和结束,从而禁用疯狂行为。