static public int SpawnProcessAndWait(string Executable, string CWD, CaptureMessageDelegate CaptureOutputInstance, params string[] Parameters) { Process Utility = new Process(); try { FileInfo Info = new FileInfo(Executable); if (!Info.Exists) { return(-1); } Utility.StartInfo.FileName = Executable; foreach (string Parameter in Parameters) { Utility.StartInfo.Arguments += Parameter + " "; } Utility.StartInfo.WorkingDirectory = CWD; Utility.StartInfo.CreateNoWindow = true; Utility.StartInfo.UseShellExecute = false; if (CaptureOutputInstance != null) { CaptureOutput = CaptureOutputInstance; Utility.StartInfo.RedirectStandardOutput = true; Utility.StartInfo.RedirectStandardError = true; Utility.OutputDataReceived += new DataReceivedEventHandler(CaptureOutputCallback); Utility.ErrorDataReceived += new DataReceivedEventHandler(CaptureOutputCallback); CaptureOutput("Launching: " + Executable + " " + Utility.StartInfo.Arguments + "(CWD: " + Utility.StartInfo.WorkingDirectory + ")"); } if (!Utility.Start()) { return(-2); } if (CaptureOutputInstance != null) { Utility.BeginOutputReadLine(); Utility.BeginErrorReadLine(); Utility.EnableRaisingEvents = true; } while (!Utility.HasExited) { Utility.WaitForExit(50); } } catch (Exception) { return(-3); } return(Utility.ExitCode); }
/// <summary> /// The process exit event. /// </summary> /// <param name="Sender">Unused.</param> /// <param name="Args">Unused.</param> private void ProcessExit(object Sender, EventArgs Args) { // Flush and close any pending messages if (CaptureMessage != null) { LaunchedProcess.CancelOutputRead(); LaunchedProcess.CancelErrorRead(); // Protect against multiple calls CaptureMessage = null; } LaunchedProcess.EnableRaisingEvents = false; bIsFinished = true; }
/// <summary> /// The process exit event. /// </summary> /// <param name="Sender">Unused.</param> /// <param name="Args">Unused.</param> private void ProcessExit( object Sender, EventArgs Args ) { // Flush and close any pending messages if( CaptureMessage != null ) { LaunchedProcess.CancelOutputRead(); LaunchedProcess.CancelErrorRead(); // Protect against multiple calls CaptureMessage = null; } LaunchedProcess.EnableRaisingEvents = false; bIsFinished = true; }
/// <summary> /// Construct a class wrapper that spawns a new child process with StdOut and StdErr optionally redirected and captured. /// </summary> /// <param name="Executable">The executable to launch.</param> /// <param name="WorkingDirectory">The working directory of the process. If this is null, the current directory is used.</param> /// <param name="InCaptureMessage">The log callback function. This can be null for no logging.</param> /// <param name="Parameters">A string array of parameters passed on the command line, and delimited with spaces.</param> /// <remarks>Any errors are passed back through the capture delegate. The existence of the executable and the working directory are checked before spawning is attempted. /// An exit code of -1 is returned if there was an exception when spawning the process.</remarks> public LaunchProcess(string Executable, string WorkingDirectory, CaptureMessageDelegate InCaptureMessage, params string[] Parameters) { CaptureMessage = InCaptureMessage; // Simple check to ensure the executable exists FileInfo Info = new FileInfo(Executable); if (!Info.Exists) { PrintLog("ERROR: Executable does not exist: " + Executable); bIsFinished = true; return; } // Set the default working directory if necessary if (WorkingDirectory == null) { WorkingDirectory = Environment.CurrentDirectory; } // Simple check to ensure the working directory exists DirectoryInfo DirInfo = new DirectoryInfo(WorkingDirectory); if (!DirInfo.Exists) { PrintLog("ERROR: Working directory does not exist: " + WorkingDirectory); bIsFinished = true; return; } // Create a new process to launch LaunchedProcess = new Process(); // Prepare a ProcessStart structure LaunchedProcess.StartInfo.FileName = Info.FullName; LaunchedProcess.StartInfo.Arguments = String.Join(" ", Parameters); LaunchedProcess.StartInfo.WorkingDirectory = DirInfo.FullName; LaunchedProcess.StartInfo.CreateNoWindow = true; // Need this for the Exited event as well as the output capturing LaunchedProcess.EnableRaisingEvents = true; LaunchedProcess.Exited += new EventHandler(ProcessExit); // Redirect the output. if (CaptureMessage != null) { LaunchedProcess.StartInfo.UseShellExecute = false; LaunchedProcess.StartInfo.RedirectStandardOutput = true; LaunchedProcess.StartInfo.RedirectStandardError = true; LaunchedProcess.OutputDataReceived += new DataReceivedEventHandler(CaptureMessageCallback); LaunchedProcess.ErrorDataReceived += new DataReceivedEventHandler(CaptureMessageCallback); } // Spawn the process - try to start the process, handling thrown exceptions as a failure. try { PrintLog("Launching: " + LaunchedProcess.StartInfo.FileName + " " + LaunchedProcess.StartInfo.Arguments + " (CWD: " + LaunchedProcess.StartInfo.WorkingDirectory + ")"); LaunchedProcess.Start(); // Start the output redirection if we have a logging callback if (CaptureMessage != null) { LaunchedProcess.BeginOutputReadLine(); LaunchedProcess.BeginErrorReadLine(); } } catch (Exception Ex) { // Clean up should there be any exception LaunchedProcess = null; bIsFinished = true; PrintLog("ERROR: Failed to launch with exception: " + Ex.Message); } }
/// <summary> /// Construct a class wrapper that spawns a new child process with StdOut and StdErr optionally redirected and captured. /// </summary> /// <param name="Executable">The executable to launch.</param> /// <param name="WorkingDirectory">The working directory of the process. If this is null, the current directory is used.</param> /// <param name="InCaptureMessage">The log callback function. This can be null for no logging.</param> /// <param name="Parameters">A string array of parameters passed on the command line, and delimited with spaces.</param> /// <remarks>Any errors are passed back through the capture delegate. The existence of the executable and the working directory are checked before spawning is attempted. /// An exit code of -1 is returned if there was an exception when spawning the process.</remarks> public LaunchProcess( string Executable, string WorkingDirectory, CaptureMessageDelegate InCaptureMessage, params string[] Parameters ) { CaptureMessage = InCaptureMessage; // Simple check to ensure the executable exists FileInfo Info = new FileInfo( Executable ); if( !Info.Exists ) { PrintLog( "ERROR: Executable does not exist: " + Executable ); bIsFinished = true; return; } // Set the default working directory if necessary if( WorkingDirectory == null ) { WorkingDirectory = Environment.CurrentDirectory; } // Simple check to ensure the working directory exists DirectoryInfo DirInfo = new DirectoryInfo( WorkingDirectory ); if( !DirInfo.Exists ) { PrintLog( "ERROR: Working directory does not exist: " + WorkingDirectory ); bIsFinished = true; return; } // Create a new process to launch LaunchedProcess = new Process(); // Prepare a ProcessStart structure LaunchedProcess.StartInfo.FileName = Info.FullName; LaunchedProcess.StartInfo.Arguments = String.Join( " ", Parameters ); LaunchedProcess.StartInfo.WorkingDirectory = DirInfo.FullName; LaunchedProcess.StartInfo.CreateNoWindow = true; // Need this for the Exited event as well as the output capturing LaunchedProcess.EnableRaisingEvents = true; LaunchedProcess.Exited += new EventHandler(ProcessExit); // Redirect the output. if (CaptureMessage != null) { LaunchedProcess.StartInfo.UseShellExecute = false; LaunchedProcess.StartInfo.RedirectStandardOutput = true; LaunchedProcess.StartInfo.RedirectStandardError = true; LaunchedProcess.OutputDataReceived += new DataReceivedEventHandler(CaptureMessageCallback); LaunchedProcess.ErrorDataReceived += new DataReceivedEventHandler(CaptureMessageCallback); } // Spawn the process - try to start the process, handling thrown exceptions as a failure. try { PrintLog( "Launching: " + LaunchedProcess.StartInfo.FileName + " " + LaunchedProcess.StartInfo.Arguments + " (CWD: " + LaunchedProcess.StartInfo.WorkingDirectory + ")" ); LaunchedProcess.Start(); // Start the output redirection if we have a logging callback if( CaptureMessage != null ) { LaunchedProcess.BeginOutputReadLine(); LaunchedProcess.BeginErrorReadLine(); } } catch( Exception Ex ) { // Clean up should there be any exception LaunchedProcess = null; bIsFinished = true; PrintLog( "ERROR: Failed to launch with exception: " + Ex.Message ); } }