williamb1024 / fs-processes Goto Github PK
View Code? Open in Web Editor NEWA library for Windows Processes and JobObjects
Home Page: https://williamb1024.github.io/fs-processes/
License: MIT License
A library for Windows Processes and JobObjects
Home Page: https://williamb1024.github.io/fs-processes/
License: MIT License
First of all great work, thanks for sharing!
Would it be possible to set a name to a JobObject?
As far as I see currently its set to null in the constructor:
_handle = Interop.Kernel32.CreateJobObject(IntPtr.Zero, null);
Is there any specific reason for this?
Relevant docs:
https://docs.microsoft.com/en-us/windows/desktop/api/WinBase/nf-winbase-createjobobjecta#parameters
Hello. Thanks for this awesome library. It's very useful!
I've just integrated it into my app and it works most of the time, but sometimes I get this exception:
System.ObjectDisposedException: Safe handle has been closed.
Object name: 'SafeHandle'.
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at Fs.Processes.JobObjects.JobObject.Notification(JobObjectMessage notifyMessage, IntPtr notifyData)
at Fs.Processes.JobObjects.JobObjectCompletionPort.IoCompletionPort.IoCompletionPortReader()
--- End of stack trace from previous location ---
at Fs.Processes.JobObjects.JobObjectCompletionPort.IoCompletionPort.<>c.<IoCompletionPortReader>b__6_0(Object edi)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
Do you have an idea what's wrong? Shouldn't I dispose the JobObject?
Here is my code:
private async Task<ProcessRunner> Start() {
Console.WriteLine($"starting process. {this.ToString()}");
await Task.Run(async () => {
try {
using var jobObject = new JobObject();
var startInfo = new Fs.Processes.CreateProcessInfo() {
FileName = executable,
WorkingDirectory = workingDir.FullName,
Arguments = string.Join(" ", arguments),
RedirectStandardOutput = redirectOutput,
RedirectStandardError = redirectError,
WindowShow = Fs.Processes.WindowShow.Hidden
};
using var process = StartProcess(jobObject, startInfo);
Task outTask = null;
Task errTask = null;
if (redirectOutput) {
process.OutputDataReceived += (s, d) => { if (d.Data != null) stdOutSb.AppendLine(d.Data); };
outTask = process.BeginReadingStandardOutputAsync();
}
if (redirectError) {
process.ErrorDataReceived += (s, d) => { if (d.Data != null) stdErrSb.AppendLine(d.Data); };
errTask = process.BeginReadingStandardErrorAsync();
}
if (outTask != null) await outTask;
if (errTask != null) await errTask;
await process.Exited;
ExitCode = process.ExitCode ?? -1;
} catch (Exception e) {
throw new ProcessRunnerException($"An exception occurred while starting a process: {this.ToString()}", e);
}
});
return this;
}
private Fs.Processes.Process StartProcess(JobObject jobObjects, Fs.Processes.CreateProcessInfo startInfo) {
if (maxMemoryMb.HasValue || maxCpuPercent.HasValue) {
var jobLimits = new JobLimits();
if (maxMemoryMb.HasValue) {
jobLimits.MaximumProcessMemory = maxMemoryMb.Value * 1024 * 1024;
}
if (maxCpuPercent.HasValue) {
jobLimits.CpuRate = new CpuRateLimit(maxCpuPercent.Value, true);
}
jobObjects.SetLimits(jobLimits);
return jobObjects.CreateProcess(startInfo);
} else {
return new Fs.Processes.Process(startInfo);
}
}
I'd be grateful for any hints :).
Repro:
using (var jobObject = new JobObject())
{
var jobLimits = new JobLimits();
jobLimits.Options = JobOptions.TerminateProcessesWhenJobClosed;
jobLimits.ActiveProcesses = 1;
jobObject.SetLimits(jobLimits);
}
Output:
Unhandled Exception:
System.ComponentModel.Win32Exception (0x80004005): The parameter is incorrect
at Fs.Processes.JobObjects.JobObject.SetLimits(JobLimits& newLimits)
Cause:
Looks like SetInformationJobObject fails if JOBOBJECT_CPU_RATE_CONTROL_INFORMATION.ControlFlags or .CpuRate is 0, which is the default value for both. This doc points out that CpuRate must not be 0, and for ControlFlags:
The scheduling policy for CPU rate control. This member can be one of the following values.
(continues to list flag values; 0 is not in the list)
However judging by a second repro, this issue only manifests if CPU limits have not been set before. If they have, the following code seems to works to disable the previous limits:
using (var jobObject = new JobObject())
{
var firstLimits = new JobLimits();
firstLimits.CpuRate = new CpuRateLimit(20, false);
jobObject.SetLimits(firstLimits);
var jobLimits = new JobLimits();
jobLimits.Options = JobOptions.TerminateProcessesWhenJobClosed;
jobLimits.ActiveProcesses = 1;
jobObject.SetLimits(jobLimits);
}
Fix:
CPU limits should only be set if they contain any values, or if they are currently enabled and should be disabled. Pseudo-code:
if (newCpuLimits.ControlFlags != 0 || currentCpuLimits.ControlFlags != 0)
SetInformationJobObject(...);
CreateProcessW call results in an AccessViolation. Appears to happen when ProcThreadAttributeList is left as IntPtr.Zero and STARTUPINFOEX flag is passed to CreateProcess flags.
Is there any known JobObject feature that is not included in this repository?
First thank you so much for writing this nice bridge library! It's very easy to use!
However our project needs to be signed so could you publish a signed version of this?
Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.