6

コマンド プロンプトから即座に実行される実行可能ファイルがありますが、System.Diagnostics.Process を使用して生成されたときに返されないようです。

基本的に、私は Accurev CLI インターフェイスの周りに .NET ライブラリ ラッパーを書いているので、各メソッド呼び出しは CLI プロセスを生成してコマンドを実行します。

これは、1 つのコマンドを除くすべてのコマンドでうまく機能します。

  accurev.exe show depots

ただし、これをコンソールから実行すると正常に動作し、.net プロセスを使用して呼び出すとハングします...使用するプロセス生成コードは次のとおりです。

    public static string ExecuteCommand(string command)
    {

        Process p = createProcess(command);

        p.Start();            
        p.WaitForExit();

        // Accurev writes to the error stream if ExitCode is non zero.
        if (p.ExitCode != 0)
        {
            string error = p.StandardError.ReadToEnd();
            Log.Write(command + " failed..." + error);
            throw new AccurevException(error);                 
        }
        else
        {
            return p.StandardOutput.ReadToEnd();
        }

    }

    /// Creates Accurev Process 
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    private static Process createProcess(string command)
    {
        Log.Write("Executing Command: " + command);

        ProcessStartInfo startInfo = new ProcessStartInfo();
        Process p = new Process();

        startInfo.CreateNoWindow = false;
        startInfo.RedirectStandardOutput = true;
        startInfo.RedirectStandardInput = true;
        startInfo.RedirectStandardError = true;

        startInfo.UseShellExecute = false;
        startInfo.Arguments = command;
        startInfo.FileName = _accurev;

        p.StartInfo = startInfo;

        return p;
    }

p.WaitForExit() でハングします。

何かアドバイス?

編集:解決しました!

出力バッファがオーバーフローすると .NET プロセスがハングするので、非同期読み取りメソッドを使用するように切り替えたところ、すべてが機能しました。

    public static string ExecuteCommand(string command)
    {
        StringBuilder outputData = new StringBuilder();

        Process p = createProcess(command);

        p.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
        {
            outputData.AppendLine(e.Data);
        };

        p.Start();
        p.BeginOutputReadLine();

        p.WaitForExit();

        // Accurev writes to the error stream if ExitCode is non zero.
        if (p.ExitCode != 0)
        {
            string error = p.StandardError.ReadToEnd();
            Log.Write(command + " failed..." + error);
            throw new AccurevException(error);                 
        }
        else
        {
            return outputData.ToString();
        }

    }   
4

3 に答える 3

2

入力を求めていますか?特に、標準入力をリダイレクトしているが、それを閉じていないことに気付きました。そのため、標準入力から読み取っている場合はハングします。

于 2008-12-16T18:58:05.133 に答える
1

WaitForExit() が実行されている間、生成されたプロセスはまだ生きていますか? デバッガをアタッチできますか?

于 2008-12-16T18:44:12.010 に答える
-2

WaitForExit() を次のように置き換えてみてください。

while (!p.WaitForExit(100))
    Console.Write(".");

もう 1 つは、UseShellExecute を true に設定し、コンソール ウィンドウが生成されるのを確認することです。そのパラメーターの複雑さについては、このページを参照してください: http://blogs.msdn.com/jmstall/archive/2006/09/28/CreateNoWindow.aspx

于 2008-12-16T19:01:32.550 に答える