Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Processing spawning issues

I have an executable that runs instantly from a command prompt, but does not appear to ever return when spawned using System.Diagnostics.Process:

Basicly, I'm writing a .NET library wrapper around the Accurev CLI interface, so each method call spawns the CLI process to execute a command.

This works great for all but one command:

  accurev.exe show depots

However, when running this from a console, it runs fine, when I call it using a .net process, it hangs...The process spawning code I use is:

    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;
    }

It hangs at p.WaitForExit().

Any advice?

EDIT: Solved!

.NET Process's hang if the output buffer overflows, I switched to using an asynchronous read method and everything works:

    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();
        }

    }   
like image 525
FlySwat Avatar asked Dec 16 '08 18:12

FlySwat


2 Answers

It is seeking for input? In particular, I notice that you are redirecting stdin, but not closing it - so if it is reading from stdin it will hang.

like image 90
Marc Gravell Avatar answered Nov 03 '22 00:11

Marc Gravell


Is the spawned process still alive while WaitForExit() is executing? Can you attach a debugger to it?

like image 27
David Norman Avatar answered Nov 03 '22 01:11

David Norman