0

Windows で実行している Qt プログラムで奇妙なエラーが発生しました。プログラムは QProcess を使用して、2 つの引数を持つ子プロセスを生成します。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 の 2 つのバージョンで実行される自動ビルド システムの一部です。また、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() 印刷呼び出しで出力されるビット) は次のとおりです。

DEBUG: scons プロセスを開始しています: "V:\Glast_Software\Toaster\tools\Python2.5\Scripts\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"

ただし、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 バッチ ファームで実行するように設計されていることを付け加えておきます。プロセスがバッチ ジョブとして実行されている場合にのみ失敗します。バッチ マシンの 1 つでコマンド ラインからこのプログラムを実行すると、完全に機能し、本来の動作を正確に実行します。なので、環境の問題かもしれません。

4

2 に答える 2

0

これは、引用符が通過していないことが原因である可能性があります(引用符はエスケープする必要がある場合があります。QProcess:: start()のドキュメントを参照してください)。

cmd.exeは、スペースやタブと同様に、引数間の区切り文字として引用符で囲まれていないコマンドラインオプションの等号を扱います。Windowsのcmdスクリプティングの非常に多くの奇妙な点の1つにすぎません。

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スクリプトでコマンドライン引数を処理する方法について私が見つけた最高のドキュメントは、TimHillの「WindowsNTシェルスクリプト」です。

アップデートで提供された例に基づいて、等号が含まれているオプションの中に引用符を埋め込んでおくとよいと思います。

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

編集-新素材

次のスクリプトには、cmdスクリプトに渡された引数から引用符を取り除くルーチンがあります。RETこのルーチンは、前述のTimHillの本のイディオム/テクニックを使用して名前が付けられた環境変数の「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 に答える
0

=標識から逃げようとしたことがありますか?\また、あなたの例のパスには、文字のエスケープが必要です。

于 2010-06-11T21:05:01.063 に答える