Skip to content

Add Process.StartAndForget APIs for fire-and-forget process launching#126078

Merged
adamsitnik merged 23 commits into
mainfrom
copilot/add-start-and-forget-apis
Apr 17, 2026
Merged

Add Process.StartAndForget APIs for fire-and-forget process launching#126078
adamsitnik merged 23 commits into
mainfrom
copilot/add-start-and-forget-apis

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 25, 2026

Adds two new static methods to Process for scenarios where you want to launch a process, get its PID, and immediately release all resources without waiting for it to exit. API approved in #125838 (comment).

Description

New APIs (Process.Scenarios.cs):

  • Process.StartAndForget(ProcessStartInfo) — validates that UseShellExecute is not set (throws InvalidOperationException if UseShellExecute = true, since on Windows shell execution may not create a new process, making it impossible to return a valid PID) and that no stream redirection is configured (throws InvalidOperationException if any RedirectStandardInput/Output/Error flag is set). Starts the process via SafeProcessHandle.Start, releases all associated resources, and returns the PID. When no standard handles are provided via ProcessStartInfo.StandardInputHandle/StandardOutputHandle/StandardErrorHandle, they are redirected to the null device by default. When possible, handle inheritance is limited to the standard handles only.
  • Process.StartAndForget(string fileName, IList<string>? arguments = null) — builds a ProcessStartInfo and delegates to the ProcessStartInfo overload above. No handles are inherited by the new process.
// Before: resource leak unless caller explicitly disposes
Process p = Process.Start("myapp", args);
int pid = p.Id;
p.Dispose(); // easy to forget

// After: idiomatic, guaranteed cleanup
int pid = Process.StartAndForget("myapp", args);

Validation guards — throws InvalidOperationException if:

  • UseShellExecute = true (shell execution may not start a new process on Windows, making it impossible to return a valid PID)
  • Any RedirectStandardInput/Output/Error flag is set (use ProcessStartInfo.StandardInputHandle = File.OpenNullHandle() instead to redirect to null explicitly)

Supporting changes:

  • Uses SafeProcessHandle.Start (introduced in PR Introduce SafeProcessHandle.Start and ProcessId #126192) directly, avoiding the need to create and dispose a Process instance
  • Reference assembly updated with both signatures, including the // this needs to come after the ios attribute due to limitations in the platform analyzer comment on [SupportedOSPlatformAttribute("maccatalyst")], consistent with other Start overloads in the file
  • New string resource StartAndForget_UseShellExecuteNotSupported in Strings.resx; the redirect-not-supported error message (CantSetRedirectForSafeProcessHandleStart) mentions both SafeProcessHandle.Start and Process.StartAndForget so users calling either API get a clear, actionable error: "The RedirectStandardInput, RedirectStandardOutput, and RedirectStandardError properties cannot be used by SafeProcessHandle.Start or Process.StartAndForget. Use the StandardInputHandle, StandardOutputHandle, and StandardErrorHandle properties."
  • The bool parameter on SafeProcessHandle.Start(ProcessStartInfo, bool) renamed from redirectToNull to fallbackToNull for clarity
  • Unused using System.IO and using System.Runtime.InteropServices directives removed from Process.Scenarios.cs
  • <summary> XML docs on both StartAndForget overloads clearly describe the fire-and-forget semantics (starts the process, releases resources, and returns the PID)
  • <remarks> paragraphs in StartAndForget(ProcessStartInfo) reordered: the standard-handle redirect paragraph is first, followed by the handle-inheritance paragraph
  • Process.Scenarios.cs added to System.Diagnostics.Process.csproj
  • Tests in StartAndForget.cs:
    • Happy paths (both overloads) in a single [ConditionalTheory] parameterized by bool useProcessStartInfo, using CreateSleepProcess with a 1-hour timeout and using declaration, with explicit Kill()/WaitForExit() cleanup in try/finally
    • StartAndForget_WithStandardOutputHandle_CapturesOutput uses the CreateProcess/RemoteExecutor pattern with SafeFileHandle.CreateAnonymousPipe to verify that ArgumentList is not ignored and that StandardOutputHandle correctly captures process output — mirrors the CanRedirectOutputToPipe pattern from ProcessHandlesTests
    • ArgumentNullException tests use AssertExtensions.Throws to verify parameter names ("startInfo" and "fileName")
    • InvalidOperationException for each redirect flag combination and for UseShellExecute = true via [Theory]
    • Null-arguments test uses cmd.exe on Windows (available on Nano Server) and true on Unix

⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.

@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-diagnostics-process
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot address my feedback

Comment thread src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs Outdated
Comment thread src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs Outdated
Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs Outdated
Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs Outdated
Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs Outdated
Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs Outdated
Copilot AI requested a review from adamsitnik March 25, 2026 09:19
Copy link
Copy Markdown
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot address my feedback

Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs Outdated
Copilot AI requested a review from adamsitnik March 25, 2026 10:28
Copy link
Copy Markdown
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot address my feedback

Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs Outdated
Comment thread src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx Outdated
…s on Unix

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/a8a7e105-927e-424f-986b-434912ec8a8e
Copilot AI requested a review from adamsitnik March 25, 2026 13:28
@danmoseley
Copy link
Copy Markdown
Member

i only see API approval issue for public static int StartAndForget(ProcessStartInfo startInfo); not the other one?

Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs Outdated
Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs
Comment thread src/libraries/System.Diagnostics.Process/tests/StartAndForget.cs
@adamsitnik
Copy link
Copy Markdown
Member

i only see API approval issue for public static int StartAndForget(ProcessStartInfo startInfo); not the other one?

Please check #125838 (comment)

@copilot please add this exact link to the PR description. And update the description based on the current state of the PR

…tAndForget test

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/3564306f-64a4-473b-8bea-cce48f30b996

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot April 16, 2026 18:18
@danmoseley
Copy link
Copy Markdown
Member

i only see API approval issue for public static int StartAndForget(ProcessStartInfo startInfo); not the other one?

Please check #125838 (comment)

@copilot please add this exact link to the PR description. And update the description based on the current state of the PR

Ah I thought api review always update the top post to final shape. ok

Copilot AI requested review from Copilot and removed request for Copilot April 16, 2026 18:32
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 16, 2026

i only see API approval issue for public static int StartAndForget(ProcessStartInfo startInfo); not the other one?

Please check #125838 (comment)...

Added the link #125838 (comment) to the PR description and updated it to reflect the current state of the PR.

Comment thread src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx
@adamsitnik adamsitnik enabled auto-merge (squash) April 16, 2026 19:44
@adamsitnik adamsitnik merged commit 6eab9a7 into main Apr 17, 2026
94 of 99 checks passed
@adamsitnik adamsitnik deleted the copilot/add-start-and-forget-apis branch April 17, 2026 00:48
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants