ChildProcessGuard 1.0.4
dotnet add package ChildProcessGuard --version 1.0.4
NuGet\Install-Package ChildProcessGuard -Version 1.0.4
<PackageReference Include="ChildProcessGuard" Version="1.0.4" />
<PackageVersion Include="ChildProcessGuard" Version="1.0.4" />
<PackageReference Include="ChildProcessGuard" />
paket add ChildProcessGuard --version 1.0.4
#r "nuget: ChildProcessGuard, 1.0.4"
#:package ChildProcessGuard@1.0.4
#addin nuget:?package=ChildProcessGuard&version=1.0.4
#tool nuget:?package=ChildProcessGuard&version=1.0.4
ChildProcessGuard
A cross-platform .NET library that ensures child processes automatically terminate when the parent process exits unexpectedly.
Features
- Cross-Platform Support: Works on Windows, Linux, and macOS
- Automatic Cleanup: Child processes terminate when the parent exits
- Windows Job Objects: Uses Job Objects for process management on Windows
- Unix Process Groups: Uses process groups on Unix systems
- Process Tree Termination: Terminates all descendant processes
- Async/Await Support: Full asynchronous API with cancellation tokens
- Process Monitoring: Real-time statistics and lifecycle events
- Batch Processing: Start multiple processes with concurrency control
- Thread-Safe: Supports concurrent operations
- Graceful Shutdown: Configurable timeout and fallback mechanisms
Requirements
- .NET Standard 2.1
- .NET 10.0+
- .NET Framework 4.7.2+ / .NET Core 2.1+ / .NET 5+
Installation
Package Manager
Install-Package ChildProcessGuard
.NET CLI
dotnet add package ChildProcessGuard
Quick Start
Basic Usage
using ChildProcessGuard;
// Simple usage with automatic cleanup
using var guardian = new ProcessGuardian();
var process = guardian.StartProcess("notepad.exe");
Console.WriteLine($"Started process with PID: {process.Id}");
// Process will be automatically terminated when guardian is disposed
Advanced Configuration
using ChildProcessGuard;
// Configure with builder pattern
using var guardian = ProcessGuardianBuilder.Debug()
.WithKillTimeout(TimeSpan.FromSeconds(10))
.WithMaxProcesses(50)
.WithDetailedLogging(true)
.WithAutoCleanup(true, TimeSpan.FromMinutes(1))
.Build();
// Set up event handlers
guardian.ProcessError += (sender, e) =>
Console.WriteLine($"Error: {e.Operation} - {e.Exception.Message}");
guardian.ProcessLifecycleEvent += (sender, e) =>
Console.WriteLine($"Event: {e.EventType} - {e.ProcessInfo}");
var process = guardian.StartProcess("myapp.exe", "--verbose");
Usage Examples
Environment Variables and Working Directory
using var guardian = new ProcessGuardian();
var envVars = new Dictionary<string, string>
{
{ "DEBUG", "true" },
{ "CONFIG_PATH", "/etc/myapp/config.json" },
{ "LOG_LEVEL", "verbose" }
};
var process = guardian.StartProcess(
"myapp.exe",
"--config config.json",
workingDirectory: "/path/to/working/dir",
environmentVariables: envVars
);
Custom ProcessStartInfo
using var guardian = new ProcessGuardian();
var startInfo = new ProcessStartInfo
{
FileName = "powershell.exe",
Arguments = "-NoProfile -Command \"Get-Process\"",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
var process = guardian.StartProcessWithStartInfo(startInfo);
string output = process.StandardOutput.ReadToEnd();
Batch Processing
using var guardian = ProcessGuardianBuilder.HighPerformance().Build();
// Prepare multiple processes
var processInfos = Enumerable.Range(1, 5)
.Select(i => new ProcessStartInfo("ping", "127.0.0.1 -n 3"))
.ToList();
// Start all processes concurrently
var processes = await guardian.StartProcessesBatchAsync(processInfos, maxConcurrency: 3);
// Wait for all to complete
bool allCompleted = await guardian.WaitForAllProcessesAsync(TimeSpan.FromSeconds(30));
Console.WriteLine($"All processes completed: {allCompleted}");
Process Monitoring
using var guardian = new ProcessGuardian();
// Start processes
guardian.StartProcess("notepad.exe");
guardian.StartProcess("calc.exe");
// Get statistics
var stats = guardian.GetStatistics();
Console.WriteLine($"Total: {stats.TotalProcesses}, Running: {stats.RunningProcesses}");
Console.WriteLine($"Memory Usage: {stats.TotalMemoryUsage / 1024 / 1024:F1} MB");
// Get detailed process information
var runningProcesses = guardian.GetProcessesByStatus(ProcessStatus.Running);
foreach (var processInfo in runningProcesses)
{
Console.WriteLine($"Process: {processInfo}");
Console.WriteLine($"Runtime: {processInfo.GetRuntime():hh\\:mm\\:ss}");
}
Async Operations
using var guardian = new ProcessGuardian();
var cts = new CancellationTokenSource();
// Start process asynchronously
var process = await guardian.StartProcessAsync("myapp.exe", cancellationToken: cts.Token);
// Terminate all processes
int terminated = await guardian.KillAllProcessesAsync(TimeSpan.FromSeconds(10));
Console.WriteLine($"Terminated {terminated} processes");
// Selective termination
int killed = await guardian.TerminateProcessesWhere(
p => p.GetRuntime() > TimeSpan.FromMinutes(5),
TimeSpan.FromSeconds(5)
);
Cross-Platform Example
using var guardian = new ProcessGuardian();
string executable, arguments;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
executable = "cmd.exe";
arguments = "/c echo Hello from Windows";
}
else
{
executable = "/bin/bash";
arguments = "-c 'echo Hello from Unix'";
}
var process = guardian.StartProcess(executable, arguments);
await process.WaitForExitAsync();
Configuration Options
ProcessGuardianOptions
var options = new ProcessGuardianOptions
{
ProcessKillTimeout = TimeSpan.FromSeconds(30), // Graceful termination timeout
EnableDetailedLogging = false, // Verbose logging
ForceKillOnTimeout = true, // Force kill if timeout exceeded
MaxManagedProcesses = 100, // Maximum concurrent processes
AutoCleanupDisposedProcesses = true, // Auto cleanup exited processes
CleanupInterval = TimeSpan.FromMinutes(5), // Cleanup check interval
UseProcessGroupsOnUnix = true, // Use process groups on Unix
ThrowOnProcessOperationFailure = false // Exception handling behavior
};
using var guardian = new ProcessGuardian(options);
Predefined Configurations
// High performance configuration
using var guardian = ProcessGuardianBuilder.HighPerformance().Build();
// Debug configuration with detailed logging
using var guardian = ProcessGuardianBuilder.Debug().Build();
// Custom configuration
using var guardian = ProcessGuardianBuilder.Default
.WithKillTimeout(TimeSpan.FromSeconds(15))
.WithMaxProcesses(200)
.WithDetailedLogging(true)
.Build();
How It Works
Windows Implementation
- Uses Windows Job Objects with
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSEflag - Automatically terminates all child processes when the job is closed
- Kernel-level guarantee for process cleanup
Unix Implementation (Linux/macOS)
- Creates process groups using
setpgid()system call - Uses
SIGTERMfor graceful termination,SIGKILLfor force termination - Terminates entire process groups to ensure all descendants are cleaned up
Cross-Platform Failsafes
- Hooks into
AppDomain.ProcessExitandConsoleCancelKeyPressevents - Falls back to basic process termination if advanced features fail
- Provides .NET 5+ features for .NET Standard 2.1 compatibility
Best Practices
- Always use
usingstatements or callDispose()explicitly - Configure appropriate timeouts based on process characteristics
- Handle events for production applications to track errors
- Use builder pattern for complex configurations
- Monitor statistics in long-running applications
- Test cross-platform behavior when targeting multiple operating systems
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues, questions, or suggestions, please open an issue on GitHub.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- No dependencies.
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on ChildProcessGuard:
| Package | Downloads |
|---|---|
|
LMSupply.Llama
llama.cpp server management for LMSupply. Provides llama-server downloading, GPU detection, and server pooling for GGUF model inference. |
GitHub repositories
This package is not used by any popular GitHub repositories.