1 using Microsoft.Extensions.Logging;
6 using System.Threading.Tasks;
14 public int Id {
get; }
17 public Task Startup {
get; }
20 public Task<int> Lifetime {
get; }
32 readonly global::System.Diagnostics.Process
handle;
51 global::System.Diagnostics.Process handle,
53 StringBuilder outputStringBuilder,
54 StringBuilder errorStringBuilder,
55 StringBuilder combinedStringBuilder,
56 ILogger<Process> logger,
59 this.processFeatures = processFeatures ??
throw new ArgumentNullException(nameof(processFeatures));
60 this.handle = handle ??
throw new ArgumentNullException(nameof(handle));
62 this.outputStringBuilder = outputStringBuilder;
63 this.errorStringBuilder = errorStringBuilder;
64 this.combinedStringBuilder = combinedStringBuilder;
66 this.logger = logger ??
throw new ArgumentNullException(nameof(logger));
68 Lifetime = WrapLifetimeTask(lifetime ??
throw new ArgumentNullException(nameof(lifetime)));
74 Startup = Task.CompletedTask;
78 Startup = Task.Factory.StartNew(() =>
82 handle.WaitForInputIdle();
84 catch (InvalidOperationException) { }
85 },
default, TaskCreationOptions.LongRunning, TaskScheduler.Current);
87 logger.LogTrace(
"Created process ID: {0}", Id);
91 public void Dispose() => handle.Dispose();
95 var result = await lifetimeTask.ConfigureAwait(
false);
96 logger.LogTrace(
"PID {0} ended with code {1}", Id, result);
103 if (combinedStringBuilder == null)
104 throw new InvalidOperationException(
"Output/Error reading was not enabled!");
105 return combinedStringBuilder.ToString().TrimStart(Environment.NewLine.ToCharArray());
111 if (errorStringBuilder == null)
112 throw new InvalidOperationException(
"Error reading was not enabled!");
113 return errorStringBuilder.ToString().TrimStart(Environment.NewLine.ToCharArray());
119 if (outputStringBuilder == null)
120 throw new InvalidOperationException(
"Output reading was not enabled!");
121 return outputStringBuilder.ToString().TrimStart(Environment.NewLine.ToCharArray());
127 if (handle.HasExited)
131 logger.LogTrace(
"Terminating PID {0}...", Id);
133 handle.WaitForExit();
137 logger.LogDebug(
"Process termination exception: {0}", e);
146 handle.PriorityClass = ProcessPriorityClass.AboveNormal;
147 logger.LogTrace(
"Set PID {0} to above normal priority", Id);
151 logger.LogWarning(
"Unable to raise process priority for PID {0}! Exception: {1}", Id, e);
156 public void Suspend() => processFeatures.SuspendProcess(handle);
159 public void Resume() => processFeatures.ResumeProcess(handle);
164 var result = await processFeatures.GetExecutingUsername(handle, cancellationToken).ConfigureAwait(
false);
165 logger.LogTrace(
"PID {0} Username: {1}", Id, result);
string GetCombinedOutput()
Get the stderr and stdout output of the IProcess
void SetHighPriority()
Set's the owned global::System.Diagnostics.Process.PriorityClass to global::System.Diagnostics.ProcessPriorityClass.AboveNormal
string GetStandardOutput()
Get the stdout output of the IProcess
Use server authentication
string GetErrorOutput()
Get the stderr output of the IProcess
readonly StringBuilder errorStringBuilder
void Terminate()
Terminates the process
async Task< string > GetExecutingUsername(CancellationToken cancellationToken)
Get the name of the account executing the IProcess.
readonly IProcessFeatures processFeatures
The IProcessFeatures for the Process.
Abstraction over a global::System.Diagnostics.Process
readonly global::System.Diagnostics.Process handle
Process(IProcessFeatures processFeatures, global::System.Diagnostics.Process handle, Task< int > lifetime, StringBuilder outputStringBuilder, StringBuilder errorStringBuilder, StringBuilder combinedStringBuilder, ILogger< Process > logger, bool preExisting)
Construct a Process
readonly ILogger< Process > logger
The ILogger for the Process
Abstraction for suspending and resuming processes.
readonly StringBuilder outputStringBuilder
readonly StringBuilder combinedStringBuilder
async Task< int > WrapLifetimeTask(Task< int > lifetimeTask)