0

我在 Windows 上运行 Qt 程序时遇到了一个奇怪的错误。该程序使用 QProcess 生成具有两个参数的子进程。传递给 QProcess::start() 方法的程序和参数具有以下形式:

"batchfile.bat" "--option1=some_value" "--option2=some_other_value\with_a\path"

由于某种原因,当这些选项进入批处理文件以处理等号时,已经转换为空格,现在看起来像:

"batchfile.bat" "--option1 some_value" "--option2 some_other_value\with_a\path"

因此,处理失败。任何想法可能导致等号被空格替换?我正在使用 Qt 下载页面上的 QT 4.6.3 框架的 mingw 构建。

编辑:这是实际的代码。我没有写它(我是一个完整的 Qt 菜鸟),但我必须尝试让它工作。它是在两个版本的 RHEL(4 和 5)、OS X 和 Windows 上运行的自动化构建系统的一部分。它在任何地方都可以正常工作,但 Windows 除外。

QProcess sconsProcess;
sconsProcess.setWorkingDirectory(build.getBuildLocation());
sconsProcess.setProcessChannelMode(QProcess::MergedChannels);

qDebug()<<"Starting scons process:"<<build.getSconsLocation()<<QString("--variant=%1-%2").arg(build.getOs()).arg(build.getVariant())<<
          QString("--source-release=%1").arg(build.getSettings().getSetting("sourceReleaseLocation", QStringList()<<"BUILDLOCATION"<<"VERSION",
                    QStringList()<<build.getBuildLocation()<<build.getBuildPackage().getVersion()).toString());
sconsProcess.start(build.getSconsLocation(), QStringList()<<QString("--variant=%1-%2").arg(build.getOs()).arg(build.getVariant())<<
          QString("--source-release=%1").arg(build.getSettings().getSetting("sourceReleaseLocation", QStringList()"BUILDLOCATION"<<"VERSION",
                    QStringList()<<build.getBuildLocation()<<build.getBuildPackage().getVersion()).toString()));
qDebug()<<"Source release build process started";

在 Windows 中转换为的实际值(在第一个 qDebug() 打印调用中打印出来的位)是:

调试:启动 scons 进程:“V:\Glast_Software\Toaster\tools\Python2.5\Scripts\scons-1.3.0.bat”“--variant=Windows-i386-32bit-vc71-Debug”“--source-发布=V:\Glast_Software\Toaster\ReleaseManagerBuild\Windows-i386-32bit-vc71\Debug\ScienceTools\LATEST-1-3163\ScienceTools-LATEST-1-3163-source.zip"

然而,在 scons-1.3.0.bat 中(我让它回显了所有执行的命令),传递的参数看起来像:

"--variant Windows-i386-32bit-vc71-Debug" "--source-release V:\Glast_Software\Toaster\ReleaseManagerBuild\Windows-i386-32bit-vc71\Debug\ScienceTools\LATEST-1-3163\ScienceTools-LATEST -1-3163-source.zip"

缺少等号。

编辑(2010 年 6 月 29 日):我应该补充一点,该系统旨在使用 LSF 批处理排队系统在小型 Windows 批处理场上运行。仅当进程作为批处理作业运行时才会失败。当我在其中一台批处理机器上从命令行运行该程序时,它运行良好,并且完全按照它应该做的那样工作。所以可能是环境问题。

4

2 回答 2

0

你试过逃避=标志吗?此外,您示例中的路径肯定需要转义\字符。

于 2010-06-11T21:05:01.063 回答
0

很有可能这是因为引号没有通过(它们可能需要转义,请参阅QProcess::start() 的文档)。

cmd.exe 将命令行选项中未引用的等号视为类似于空格或制表符的参数之间的分隔符。只是 Windows cmd 脚本中许多奇怪的地方之一:

C:\test>type c:\util\cmdechoargs.cmd
@echo off
setlocal
set /a i=0
echo args[*]: %*
:loop
if {%1} == {} goto :eof
echo argv[%i%]: %1
set /a i=%i% + 1
shift
goto :loop


C:\test>cmdechoargs testing=123
args[*]: testing=123
argv[0]: testing
argv[1]: 123

C:\test>cmdechoargs "testing=123"
args[*]: "testing=123"
argv[0]: "testing=123"

关于如何在 Windows cmd 脚本中处理命令行参数,我遇到的最好的文档是Tim Hill 的“Windows NT Shell Scripting” ——只需一分钱就可以使用!

根据更新中给出的示例,我认为您可能希望在其中包含等号的选项中嵌入引号:

"\"--variant=%1-%2\""
"\"--source-release=%1\""

编辑——新材料

下面的脚本有一个例程,它将去掉传递给 cmd 脚本的参数的引号。RET该例程在使用我上面提到的 Tim Hill 的书中的成语/技术命名的环境变量中返回“dequoted”参数。我从此处的示例中窃取了一些取消引用的代码:http://ss64.com/nt/syntax-esc.html 但使其在处理空引号时更加健壮。

@echo off
setlocal
set /a i=0
echo args[*]: %*
:loop
if {%1} == {} goto :eof
echo.
echo argv[%i%]: %1

call :dequote %1
set dequoted_arg=%RET%
echo argv[%i%] ^(dequoted^): %dequoted_arg%

set /a i=%i% + 1
shift
goto :loop


:dequote
setlocal
SET _string=###%1###
if {%_string%} == {######} goto :dequote_empty
if {%_string%} == {###""###} goto :dequote_empty
SET _string=%_string:"###=%
SET _string=%_string:###"=%
SET _string=%_string:###=%
goto :dequote_done

:dequote_empty
set _string=

:dequote_done
endlocal & (set RET=%_string%) & goto :eof

这种事情就是为什么除了最简单的任务之外,您要避免(在我看来)cmd 脚本。但是,我希望这可以帮助您通过批处理文件将未引用的参数传递给您的 scons 进程。

于 2010-06-11T21:33:15.120 回答