6 Stimmen

.NET-Verarbeitung verursacht Probleme

Ich habe eine ausführbare Datei, die sofort von einer Eingabeaufforderung ausgeführt wird, aber nicht scheint, jemals zurückkehren, wenn mit System.Diagnostics.Process:

Grundsätzlich schreibe ich einen .NET-Bibliotheks-Wrapper um die Accurev-CLI-Schnittstelle, so dass jeder Methodenaufruf den CLI-Prozess zur Ausführung eines Befehls auslöst.

Dies funktioniert bei allen Befehlen bis auf einen hervorragend:

  accurev.exe show depots

Jedoch, wenn diese von einer Konsole ausgeführt wird, läuft es gut, wenn ich es mit einem .net-Prozess aufrufen, hängt es... Der Prozess spawnen Code, den ich verwenden ist:

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

Er bleibt bei p.WaitForExit() hängen.

Haben Sie einen Rat?

EDIT : Gelöst!

NET Process's hängen, wenn der Ausgabepuffer überläuft, habe ich zu einer asynchronen Lesemethode gewechselt und alles funktioniert:

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

    }

2voto

Marc Gravell Punkte 970173

Sie bittet um Beiträge? Insbesondere fällt mir auf, dass Sie stdin umleiten, aber nicht schließen - wenn es also von stdin liest, bleibt es hängen.

1voto

David Norman Punkte 18770

Ist der gespawnte Prozess noch am Leben, während WaitForExit() ausgeführt wird? Können Sie einen Debugger daran anschließen?

-2voto

FryGuy Punkte 8474

Versuchen Sie, die Funktion WaitForExit() durch etwas wie dieses zu ersetzen:

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

Sie können auch versuchen, UseShellExecute auf true zu setzen und zu beobachten, wie das Konsolenfenster erzeugt wird. Auf dieser Seite finden Sie die Feinheiten dieses Parameters: http://blogs.msdn.com/jmstall/archive/2006/09/28/CreateNoWindow.aspx

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X