2

私は小さなC++プログラムを書いています。これには、スペースを含むパスの送信など、多くの引数を使用して.exeプロセスを開始するため、パスを二重引用符で囲む必要があります。\"エスケープ文字を使用したことを覚えています。

私はこのプロセスを開始するためのさまざまな方法を試しましたが、最終的にはsystem()に行き着き、開始コードをできるだけ最小限にしようとしました。

私はこのコードを持っています:

string ExpandEnvironmentVariables(string input)
{
    char buffer[512];
    ExpandEnvironmentStringsA(input.c_str(), buffer, sizeof(buffer) / sizeof(*buffer));
    return buffer;
}

私が知る限り、これは問題なく動作します。

これが私がプロセスを開始するために使用しているコードです(すべての変数はstd :: stringです)。これは正常に機能しますが、渡したいすべての引数が含まれているわけではありません。

system(ExpandEnvironmentVariables("\"" + path + "\" " + arg1 + " -c ").c_str());

これは機能しません:

system(ExpandEnvironmentVariables("\"" + path + "\" " + arg1 + " -c \"").c_str());

余分な二重引用符が追加されていることに注意してください。プロセスエラーではなく、プロセスが起動することさえありません。

プロセスモニターを使用してプロセスの起動を検出していますが、二重引用符を追加するとすぐにprocess.exeが表示されません。ただし、これが私がプロセスを開始したいものです(これも機能しません)

system(ExpandEnvironmentVariables("\"" + path + "\" " + arg1 + " -c \"" + arg2 + "\"" + arg3 + arg4 + " " + arg5 + arg6 + " " + arg6 + "\\" + arg7).c_str());

二重引用符を組み合わせようとしましたが、これも機能しません。

system(ExpandEnvironmentVariables("\"" + path + "\" " + arg1 + " -c \"test\"").c_str());

最後に、長さが気になりました。3番目の二重引用符の追加はそれを壊すものです。ただし、その前の長さは134文字です。ただし、実際の開始ルーチンの長さは346文字にする必要があります。これは長すぎないですよね?

プログラムをデバッグし、フォーマットされた文字列を取得してコマンドプロンプトに貼り付けると、プロセスが完全に開始されます。これらの余分な引用符を使用すると、完全にフォーマットされます。しかし、C ++で開始することはできません!

ここで何が起こっているのか誰か知っていますか?それは私を絶対に怒らせています!あなたが提供できるどんな助けやアドバイスにも感謝します。

4

1 に答える 1

1

編集:

2つの回避策を提案します。

  1. 引数の前後を使用する代わりに、各スペース文字を;"に置き換えることができます。\"置換を正しく行うには\\"、置換文字列として指定する必要があります。最初は引数を指定せずに(コマンド名のみ)試してみて、拡張できるかどうかを確認してください。

  2. コマンドライン全体をバッチファイルに書き込み(Windowsを使用しているようです)、そのファイルを実行します。

Win32の二重引用符のエスケープルールに関するこの投稿も確認してください。

これを試して:

system(ExpandEnvironmentVariables("\"" + path + "\" " + arg1 + " -c \\\"").c_str());

3に注意して\ください:バックスラッシュをシェルに渡します(コマンドラインのように)。一度だけエスケープする"と、シェルはそれをそのように受け取り、文字列区切り文字として解釈します。あなたが望むのは、シェルがそれをエスケープして受け取ることです。したがって、の\前にダブルがあり\"ます。

于 2012-05-05T09:37:50.280 に答える