2012-12-28 15 views
7

Nach & erklärt, wie unten einen Prozess beginnen:Überprüfen, ob der Prozess einen Fehler zurückgegeben hat C#

System.Diagnostics.Process _p = new System.Diagnostics.Process(); 
..... 
..... 
.... 
_p.Start(); 

Es gibt zwei Möglichkeiten jetzt: Entweder ein Ausgang oder ein Fehler.

Falls ein Fehler auftritt, gibt es eine Eigenschaft der Process Klasse, durch die zu wissen ist, ob ein Fehler aufgetreten ist?

Ich bin die Umleitung der Standard-Ausgabe, ich möchte Standard Fehler as warned in MSDN nicht umleiten. Auch ich möchte nicht verwenden: BeginOutputReadLine();

Gibt es Alternativen?

Vielen Dank.

+4

Ist der Prozess, den Sie beginnen Rückkehr richtigen Exit-Codes (zB '0' für den Erfolg, '

http://ss64.com/nt/cmd.html für cmd.exe Hilfe hilft 1' für Fehler)? Wenn dies der Fall ist, können Sie '_p.ExitCode' überprüfen, sobald der Prozess beendet wurde. –

+0

@Cory Vielen Dank. Meine benutzerdefinierten Prozesse, die ich gestartet habe, hatten keine Exit-Codes. Aber jetzt habe ich diese implementiert und checked _p.ExitCode und seine Arbeitsweise perfekt. Noch einmal vielen Dank. –

+0

Sie sagen, Sie wollen nicht std err 'wie in MSDN gewarnt '(http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandarderror.aspx) umleiten, vielleicht ist es mein Englisch Verständnis, aber ich sehe nirgendwo in dem Artikel warnt Sie gegen Umleitung std err, nur wie man es zu verhindern, ein Deadlock – Jason

Antwort

12

Ich habe einen Dienst, die Prozesse starten muss, und warten, bis sie zu verlassen und ich so etwas wie:

process.Start(); 
int timeout = ... // some normal value in milliseconds 

process.WaitForExit(timeout); 

try 
{ 
    //ExitCode throws if the process is hanging 
    return (CommandErrorCode)process.ExitCode; 
} 
catch (InvalidOperationException ioex) 
{ 
    return CommandErrorCode.InternalError; 
} 

wo CommandErrorCode etwas wie

public enum CommandErrorCode 
{ 
    Success = 0, 
    //some other values I know from the processes that are managed 
    InternalError = 256 // the ExitCode is a byte, so this out of that range 
} 

Btw ist, leite ich beide Standardausgabe und Standardfehler, und verwenden BeginXXXReadLine und die XXXDataReceived-Handler, und haben keine Probleme, aber die Prozesse, die ich verwende, sind bekannt, gut definiert und gut erzogen.

+0

Im oben genannten try-Block haben Sie erwähnt, dass ExitCode ausgelöst wird, wenn der Prozess hängt. Exit-Code wird nicht nur ausgegeben, wenn der Prozess beendet wird und nicht hängt. Bitte korrigieren Sie mich, da ich nicht weiß, was passieren kann, wenn der Prozess aufhört. –

+2

Wenn der Prozess innerhalb der Timeout-Zeit normal beendet wird, gibt 'ExitCode' einen Wert zurück. Wenn der Prozess aufhört, wird er überhaupt nicht beendet, und der Aufruf von "ExitCode" bei einem laufenden Prozess führt zum Auslösen einer "InvalidOperationException". Sie können auch das 'Process.Exited'-Ereignis und die' Process.Kill'-Methode verwenden, um die Prozesslebensdauer zu verwalten. – SWeko

+0

+1 & danke für die Info. Das war sehr hilfreich für mich. –

2

ist hier ein Code-Schnipsel, hoffen, dass diese

private int CallShell(string exeCommand, string Parameters) 
        { 
            //http://ss64.com/nt/cmd.html 
            /* 
            This function will actually take the shell string and envoke the appropriate process 
             passing it the arguments to do the work 
            */ 

            // Initialize the process and its StartInfo properties. 
            System.Diagnostics.Process ProcessEXE = new System.Diagnostics.Process(); 

            logger.DebugFormat("About to Start Process - {0} {1}",exeCommand, Parameters); 
            try 
            { 

                ProcessEXE.StartInfo.FileName = exeCommand; 


                // Set UseShellExecute to false for redirection. 
                //  false if the process should be created directly from the executable file 
                ProcessEXE.StartInfo.UseShellExecute = false; 
                ProcessEXE.StartInfo.WorkingDirectory = System.Environment.CurrentDirectory; 

                //EnableRaisingEvents property indicates whether the component should be notified when the operating system has shut down a process 

                ProcessEXE.StartInfo.Arguments = Parameters; 

                ProcessEXE.StartInfo.RedirectStandardOutput = true; 
                ProcessEXE.StartInfo.RedirectStandardError = true; 
                ProcessEXE.EnableRaisingEvents = true; 
                ProcessEXE.StartInfo.CreateNoWindow = true; 

                ProcessEXE.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(ProcessEXE_OutputDataReceived); 
                ProcessEXE.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(ProcessEXE_OutputDataReceived); 

                logger.DebugFormat("Process Started."); 
                ProcessEXE.Start(); 


                // Start the asynchronous read of the sort output stream. 
                ProcessEXE.BeginErrorReadLine(); 
                ProcessEXE.BeginOutputReadLine(); 

                //The WaitForExit overload is used to make the current thread wait until the associated process terminates 
                logger.DebugFormat("Process Waiting for exit."); 
                ProcessEXE.WaitForExit(); 

                if (ProcessEXE.ExitCode == 0) 
                { 
                    logger.Debug(string.Format("Shell Process exited with exit code {0}", ProcessEXE.ExitCode)); 
                } 
                else 
                { 
       // throw error here if required - check the return error code 
                    logger.Warn(string.Format("Shell Process exited with exit code {0}", ProcessEXE.ExitCode)); 
                } 
            } 
            catch (Exception ex) 
            { 
                throw new Exception(string.Format("Method:{0}", ex.TargetSite), ex); 
            } 

            return ProcessEXE.ExitCode; 
        } 


void ProcessEXE_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e) 
        { 
            try 
            { 
                StringBuilder sb = new StringBuilder(string.Empty); 
                if (e == null) return; 

                if (e.Data == null) 
                { 
                    //No processing 
                } 
                else 
                { 
                   // your logic to detect error msg out from output - if at all required 
                } 

                if (sb.ToString().ToUpper().IndexOf("ERROR") > 0) 
                { 
                    string smessage = "Error text found in  output."; 

       // do your error response action here . 

                } 
            } 
            catch (Exception exp) 
            { 
                logger.ErrorFormat("Error in ProcessEXE_OutputDataReceived Message:{0}", exp.Message); 
                logger.ErrorFormat("Error in ProcessEXE_OutputDataReceived Data Received:{0}", e.Data); 

      // either throw error msg or kill the process 
            } 
            finally 
            { 
                // Not throwing the exception 
            } 
        } 
Verwandte Themen