/// <summary> /// Creates a new process and assigns the process to the job object. /// </summary> /// <param name="createProcessInfo">The <see cref="CreateProcessInfo"/> that contains information this is /// used to start the process, including the file name and any command-line arguments.</param> /// <returns>A <see cref="Process"/> instance that represents the newly created process.</returns> public Process CreateProcess(CreateProcessInfo createProcessInfo) { if (createProcessInfo == null) { throw new ArgumentNullException(nameof(createProcessInfo)); } return(CreateProcess(createProcessInfo, ProcessOptions.None)); }
public async Task RunAsync() { using (var jobObject = new JobObject()) { // setup some limits, we do this before starting any processes, but it's not // required.. var jobLimits = new JobLimits(); jobLimits.CpuRate = new CpuRateLimit(10.0m, false); jobLimits.Options = JobOptions.TerminateProcessesWhenJobClosed; jobLimits.ActiveProcesses = 3; jobObject.SetLimits(jobLimits); // setup a few event handlers.. jobObject.ProcessAdded += (s, e) => Console.WriteLine($"Process {e.ID} added."); jobObject.ProcessExited += (s, e) => Console.WriteLine($"Process {e.ID} exited."); jobObject.ProcessLimitExceeded += (s, e) => Console.WriteLine("Process limit exceeded."); jobObject.CpuRateLimitExceeded += (s, e) => Console.WriteLine("CPU rate limit exceeded."); // configure CPU rate notification.. var jobNotifications = new JobNotifications(); jobNotifications.CpuRate = new RateControl(RateControlInterval.Short, RateControlTolerance.Low); // start some ping processes... var cpiPing = new CreateProcessInfo { FileName = "ping.exe", ArgumentsList = { "8.8.8.8", "-t" } }; // create ping processes, directly through the JobObject, this will create the process // and associate the process with the JobObject .. for (int iIndex = 0; iIndex < 10; iIndex++) { try { using (var process = jobObject.CreateProcess(cpiPing)) Console.WriteLine($"Created Process {process.Id}"); } catch (System.ComponentModel.Win32Exception ex) when(ex.NativeErrorCode == ERROR_NOT_ENOUGH_QUOTA) { // ERROR_NOT_ENOUGH_QUOTA happens if the process cannot be assigned to the job object // because of the active process limit.. Console.WriteLine("JobObject.CreateProcess failed, due to process limit."); } } Console.WriteLine("[enter] to terminate active processes."); Console.ReadLine(); jobObject.Kill(); // wait for JobObject to become idle.. await jobObject.Idle; } }
public async Task RunAsync() { var processInfo = new CreateProcessInfo { FileName = "ping.exe", ArgumentsList = { "8.8.8.8" } }; using (var process = new Process(processInfo)) { await process.Exited; } }
public async Task RunAsync() { var processInfo = new CreateProcessInfo { FileName = "ping.exe", ArgumentsList = { "8.8.8.8" }, RedirectStandardError = true, RedirectStandardOutput = true }; using (var process = new Process(processInfo)) { process.OutputDataReceived += (s, d) => { // Data is null when EOF is read if (d.Data != null) { Console.Write("StdOut: "); Console.WriteLine(d.Data); } }; process.ErrorDataReceived += (s, d) => { // Data is null when EOF is read if (d.Data != null) { Console.Write("StdErr: "); Console.WriteLine(d.Data); } }; // passing 'false' to these methods tells the async reader to call the event handlers // every time data is received, rather than waiting for a CR, LF or CRLF pair terminator. var outTask = process.BeginReadingStandardOutputAsync(false); var errTask = process.BeginReadingStandardErrorAsync(false); // wait for the process to exit.. await process.Exited; // the outTasks and errTask are completed when EOF is read.. await outTask; await errTask; } }
/// <summary> /// Creates a new process and assigns the process to the job object. /// </summary> /// <param name="createProcessInfo">The <see cref="CreateProcessInfo"/> that contains information this is /// used to start the process, including the file name and any command-line arguments.</param> /// <param name="processOptions">A set of <see cref="ProcessOptions"/> that controls how the new process /// is created.</param> /// <returns>A <see cref="Process"/> instance that represents the newly created process.</returns> public Process CreateProcess(CreateProcessInfo createProcessInfo, ProcessOptions processOptions) { if (createProcessInfo == null) { throw new ArgumentNullException(nameof(createProcessInfo)); } CheckDisposed(); Process newProcess = null; try { // create the process, forcing it to be suspened.. newProcess = new Process(createProcessInfo, processOptions | ProcessOptions.Suspended); // assign the process to this job object.. if (!Interop.Kernel32.AssignProcessToJobObject(Handle, newProcess.Handle)) { throw Errors.Win32Error(); } // if the process wasn't requested to be started in a suspended state then // resume the process now.. if ((processOptions & ProcessOptions.Suspended) == 0) { newProcess.Resume(); } } catch { // if assignment fails, kill the process and dispose of it.. newProcess?.Kill(); newProcess?.Dispose(); throw; } return(newProcess); }