Coder Social home page Coder Social logo

williamb1024 / fs-processes Goto Github PK

View Code? Open in Web Editor NEW
10.0 10.0 4.0 687 KB

A library for Windows Processes and JobObjects

Home Page: https://williamb1024.github.io/fs-processes/

License: MIT License

C# 100.00%
async-await csharp jobobject process windows

fs-processes's People

Contributors

bormm avatar williamb1024 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fs-processes's Issues

ObjectDisposedException

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 :).

JobObject.SetLimits fails if CpuRate is not set

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(...);

Signed version?

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!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.