-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Background and motivation
There is currently no easy, cross-platform way to start a detached process in .NET. A detached process is one that:
- Does not belong to the parent process's process group
- Continues running after the parent process exits
- Has its standard input/output/error disconnected from the parent
This is a common requirement for scenarios such as:
- Starting long-running server applications or daemons
- Launching GUI applications from console tools
- Creating background services that outlive the parent process
Currently, achieving this requires platform-specific workarounds like invoking shell commands like nohup <command> & through /bin/sh, which requires concatenating arguments as strings and loses the ability to obtain the child process ID (see #104210)
These workarounds are error-prone, not portable, and don't provide consistent behavior across platforms.
API Proposal
The proposal introduces a new SafeProcessHandle method for starting and managing detached processes in a platform-agnostic manner.
namespace Microsoft.Win32.SafeHandles;
public partial class SafeProcessHandle
{
public static SafeProcessHandle Start(ProcessStartOptions options, SafeFileHandle? input, SafeFileHandle? output, SafeFileHandle? error);
public static SafeProcessHandle StartSuspended(ProcessStartOptions options, SafeFileHandle? input, SafeFileHandle? output, SafeFileHandle? error);
// Starts a new detached process with standard input, output, and error redirected to NUL.
// On Windows, the process is started with DETACHED_PROCESS and CREATE_NEW_PROCESS_GROUP flags.
// On macOS, the process is started with POSIX_SPAWN_SETSID.
// On other Unix systems, the process calls setsid() after fork and before exec.
+ public static SafeProcessHandle StartDetached(ProcessStartOptions options);
}Usage Example
The following example demonstrates how to start a detached process:
using Microsoft.Win32.SafeHandles;
using System.Diagnostics;
ProcessStartOptions options = new("myserver") { Arguments = { "--port", "8080" } };
// Start a detached server process
SafeProcessHandle handle = SafeProcessHandle.StartDetached(options);Risks
Starting a detached process is advanced scenario, when used incorrectly, it can lead to issues such as orphaned processes that continue running indefinitely.