Skip to content

[Process]: Start detached process #124334

@adamsitnik

Description

@adamsitnik

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions