MCPInstall

process-api-net11

Provides guidance on the new System.Diagnostics.Process APIs introduced in .NET 11: Process.Run, Process.RunAndCaptureText, Process.StartAndForget, Process.ReadAllText/Bytes/Lines, KillOnParentExit, InheritedHandles, and StartDetached. USE FOR: starting, orchestrating, or capturing output from external processes in applications targeting net11.0 or later. DO NOT USE FOR: applications targeting .NET 10 or earlier, or basic pre-.NET 11 Process.Start usage without new APIs.

Installs
680
Last 24h
+58
Trending rank
#3049
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/dotnet/skills --skill process-api-net11
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads process-api-net11 automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Process API Improvements — .NET 11

New APIs added to System.Diagnostics.Process in .NET 11 simplify process management, eliminate boilerplate, and prevent common deadlock patterns when capturing output in .NET 11 or later applications.

When to Use

  • Running or orchestrating external processes in a .NET 11 (or later) project.
  • Needing to start a process, wait for it to exit, and capture its output/error streams without risking deadlocks (Process.RunAndCaptureText[Async]).
  • Wanting to ensure child processes are automatically terminated when the parent process exits (KillOnParentExit).
  • Requiring lightweight, low-overhead process creation via SafeProcessHandle on supported platforms.
  • Requiring fine-grained control over handle inheritance (InheritedHandles) or starting detached processes (StartDetached).

When Not to Use

  • The project targets .NET 10 or earlier — these APIs are not available before .NET 11.
  • The default Process.Start() is sufficient and does not require output capturing or advanced lifecycle rules.

Target Framework

<TargetFramework>net11.0</TargetFramework>

New APIs

Types

Before using the new convenience methods, note the following types. Use the framework types directly:

TypeKindRead-only properties
ProcessExitStatusSealed classint ExitCode, bool Canceled, PosixSignal? Signal
ProcessTextOutputSealed classProcessExitStatus ExitStatus, string StandardOutput, string StandardError, int ProcessId
ProcessOutputLineReadonly structstring Content, bool StandardError

ProcessExitStatus describes the outcome of a completed process. Interpret ExitCode using the external command's contract; there is no universal Success property. ProcessTextOutput contains the exit status, captured output and error text, and process ID. ProcessOutputLine identifies one output line and whether it came from standard error.

High-Level Convenience APIs

Static Methods

The ProcessStartInfo overloads below require UseShellExecute = false, which is the default for .NET.

Process.Run / Process.RunAsync

Starts a process and waits for it to exit, returning the exit status. Does not capture standard output or error. Passing silent: true discards standard output and error by internally redirecting standard handles to the NUL device. On timeout or cancellation, the process is killed.

public static ProcessExitStatus Run(string fileName, IEnumerable<string>? arguments = null, bool silent = false, TimeSpan? timeout = null)
public static Task<ProcessExitStatus> RunAsync(string fileName, IEnumerable<string>? arguments = null, bool silent = false, CancellationToken cancellationToken = default)
public static ProcessExitStatus Run(ProcessStartInfo startInfo, TimeSpan? timeout = null)
public static Task<ProcessExitStatus> RunAsync(ProcessStartInfo startInfo, CancellationToken cancellationToken = default)
Process.RunAndCaptureText / Process.RunAndCaptureTextAsync

Starts a process, captures both standard output and error, and waits for it to exit. Extremely useful for avoiding deadlocks on stream redirection. On timeout or cancellation, the process is killed.

When using the ProcessStartInfo overloads, the caller is responsible for setting RedirectStandardOutput = true and RedirectStandardError = true on ProcessStartInfo (because BCL APIs cannot modify the input arguments they were given).

public static ProcessTextOutput RunAndCaptureText(string fileName, IEnumerable<string>? arguments = null, TimeSpan? timeout = null)
public static Task<ProcessTextOutput> RunAndCaptureTextAsync(string fileName, IEnumerable<string>? arguments = null, CancellationToken cancellationToken = default)
public static ProcessTextOutput RunAndCaptureText(ProcessStartInfo startInfo, TimeSpan? timeout = null)
public static Task<ProcessTextOutput> RunAndCaptureTextAsync(ProcessStartInfo startInfo, CancellationToken cancellationToken = default)
Process.StartAndForget

There is a common misconception that when a process is disposed, it's also being killed. This is not the case, as Process.Dispose only releases the resources associated with the process, but does not kill it.

To make it easier to start a process without the need to worry about disposing it, Process.StartAndForget was introduced. The method starts an executable, returns its ID, and immediately releases all handle resources associated with it. Standard handles not supplied through StandardInputHandle, StandardOutputHandle, or StandardErrorHandle go to the null device by default.

StartAndForget throws InvalidOperationException if UseShellExecute or any RedirectStandardInput, RedirectStandardOutput, or RedirectStandardError flag is true. Use a capture or streaming API if output needs to be read.

public static int StartAndForget(string fileName, IEnumerable<string>? arguments = null)
public static int StartAndForget(ProcessStartInfo startInfo)

Instance Methods

These methods are called on a Process instance to directly read stdout and stderr, guaranteeing no OS pipe buffer overflow deadlocks.

Note: Calling these methods requires RedirectStandardOutput = true and RedirectStandardError = true on the ProcessStartInfo passed to Process.Start.

public (string StandardOutput, string StandardError) ReadAllText(TimeSpan? timeout = null)
public Task<(string StandardOutput, string StandardError)> ReadAllTextAsync(CancellationToken cancellationToken = default)
public (byte[] StandardOutput, byte[] StandardError) ReadAllBytes(TimeSpan? timeout = null)
public Task<(byte[] StandardOutput, byte[] StandardError)> ReadAllBytesAsync(CancellationToken cancellationToken = default)
public IEnumerable<ProcessOutputLine> ReadAllLines(TimeSpan? timeout = null)
public IAsyncEnumerable<ProcessOutputLine> ReadAllLinesAsync(CancellationToken cancellationToken = default)

Example of deconstructing the tuple return:

var (stdout, stderr) = await process.ReadAllTextAsync();

ProcessStartInfo Properties

KillOnParentExit

Ensures that the spawned child process is terminated when the current (parent) process exits (including fatal crash and being force killed). Works across Windows, Linux, and Android.

public bool KillOnParentExit { get; set; }

In cross-platform code, guard the property assignment with a supported-platform check, not only the assigned value. If automatic teardown is required, fail explicitly on an unsupported platform instead of starting an unprotected child process. KillOnParentExit requires UseShellExecute = false.

InheritedHandles

Provides precise control over which handles (file descriptors) are inherited by the child process, preventing accidental resource leaks.

  • Standard handles (stdin, stdout, stderr) are always included (no need to add them to the list).
  • Setting the list to an empty list means only standard handles get inherited.
  • Only SafeFileHandle and SafePipeHandle instances are allowed as of today.
  • No global lock is used when spawning new processes on Windows (important for tuning projects that spawn multiple processes in parallel).
  • Concurrent process starts must not pass the same handle in InheritedHandles: the runtime temporarily changes its inheritance flags. Serialize starts that share a handle, or use separate handles for each concurrent start.
  • Do not enable inheritance on the handles before passing them; other process-start APIs could then inherit them unintentionally.
  • On Unix systems without native handle-inheritance control, setting this property can severely reduce process-start performance.
  • A non-null list requires UseShellExecute = false and cannot be combined with a non-empty UserName.
public IList<SafeHandle>? InheritedHandles { get; set; }

StartDetached

Starts the process detached from the parent's terminal or job session, ensuring it survives the parent's exit.

public bool StartDetached { get; set; }

StartDetached requires UseShellExecute = false.


Examples

1. One-Line Run and Capture Output

Run a process and safely read all output text without stream deadlock risks. For simple CLI operations that don't need cancellation or async scalability, prefer the synchronous overload:

using System;
using System.Diagnostics;

// Run 'git status' and capture output
ProcessTextOutput result = Process.RunAndCaptureText("git", ["status"]);

if (result.ExitStatus.ExitCode == 0)
{
    Console.WriteLine($"Git Output: {result.StandardOutput}");
}
else
{
    Console.WriteLine($"Failed with exit code: {result.ExitStatus.ExitCode}");
    Console.WriteLine($"Error: {result.StandardError}");
}

2. Auto-Killing Child Processes on Parent Exit

On Windows, Linux, and Android, ensure a long-running background worker process is killed when the main application terminates. On other platforms, this example stops before starting the child process:

using System;
using System.Diagnostics;

ProcessStartInfo startInfo = new("dotnet", ["run", "--project", "BackgroundWorker.csproj"]);

if (OperatingSystem.IsWindows() || OperatingSystem.IsLinux() || OperatingSystem.IsAndroid())
{
    startInfo.KillOnParentExit = true;
}
else
{
    throw new PlatformNotSupportedException("This example requires Windows, Linux, or Android.");
}

using Process process = Process.Start(startInfo)!;
// The background worker is now tied to this process's lifecycle

3. Read All Lines From Output

Start a process and read its output lines safely:

using System;
using System.Diagnostics;
using System.Threading.Tasks;

ProcessStartInfo startInfo = new("ping", ["127.0.0.1"])
{
    RedirectStandardOutput = true,
    RedirectStandardError = true
};

using Process process = Process.Start(startInfo)!;
// Read all output lines safely and asynchronously
await foreach (ProcessOutputLine line in process.ReadAllLinesAsync())
{
    string prefix = line.StandardError ? "[Err]" : "[Out]";
    Console.WriteLine($"{prefix} > {line.Content}");
}

4. Read Entire Output Deadlock-Free (Tuple Return)

Start a process with custom ProcessStartInfo and read both stdout and stderr into a deconstructed tuple without buffer deadlocks:

using System;
using System.Diagnostics;
using System.Threading.Tasks;

ProcessStartInfo startInfo = new("git", ["diff"])
{
    RedirectStandardOutput = true,
    RedirectStandardError = true
};

using Process process = Process.Start(startInfo)!;
var (stdout, stderr) = await process.ReadAllTextAsync();

Console.WriteLine($"Diff output: {stdout}");

5. Start and Forget (Fire & Forget)

Launch a helper executable without holding onto system handle structures:

using System;
using System.Diagnostics;

// Fire and forget, getting back only the process ID
int pid = Process.StartAndForget("notepad.exe");
Console.WriteLine($"Notepad started with PID: {pid}");

FAQ

What does the process-api-net11 skill do?

Provides guidance on the new System.Diagnostics.Process APIs introduced in .NET 11: Process.Run, Process.RunAndCaptureText, Process.StartAndForget, Process.ReadAllText/Bytes/Lines, KillOnParentExit, InheritedHandles, and StartDetached. USE FOR: starting, orchestrating, or capturing output from external processes in applications targeting net11.0 or later. DO NOT USE FOR: applications targeting .NET 10 or earlier, or basic pre-.NET 11 Process.Start usage without new APIs.

How do I install process-api-net11?

Run npx skills add https://github.com/dotnet/skills --skill process-api-net11 in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/process-api-net11/ (personal) or .claude/skills/process-api-net11/ (project).

Which AI agents can use process-api-net11?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is process-api-net11 safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains process-api-net11?

It is published by dotnet in dotnet/skills. It has 680 recorded installs.

More from dotnet/skills

View all →

Review and optimize application data access that uses Entity Framework Core (EF Core). Use for EF Core performance and correctness reviews of services, repositories, imports, and background jobs: slow or memory-heavy queries, excessive round-trips, hidden SaveChanges, premature materialization, dynamic query construction, result-graph tracking, bulk writes, DbContext lifetime or overlapping operations, search semantics, paging, raw SQL, and model/index coverage. Use whether or not EF Core owns the schema. For EF Core, not Dapper or raw ADO.NET.

run-tests

dotnet/skills

ALWAYS USE before running .NET tests or answering with a test command or flags. Trigger on "run the tests", "exact dotnet test command", one test/class/category/trait/target framework, combined filters, --filter-query, --no-build, --diag, diagnostic logs, TRX, coverage collection, crash/hang dumps, filter errors, or unrecognized options. Chooses repository-compatible classic, VSTest, bridged MTP, or native MTP syntax for MSTest/xUnit/NUnit/TUnit. DO NOT USE for platform identification alone (platform-detection), writing or debugging test code, interpreting an existing coverage report, CI investigation, migration, or a persistent hot reload/watch loop.

Testing & QA5.8K installs

Scans .NET code for 50 performance anti-patterns across async, memory, strings, collections, LINQ, regex, serialization, and I/O with tiered severity classification. Use when analyzing .NET code for optimization opportunities, reviewing hot paths, or auditing allocation-heavy patterns.

Backend & APIs5K installs

test-anti-patterns

dotnet/skills

Audit a test file or suite; produce a severity-ranked diagnostic report. ALWAYS USE for tests that verify nothing, missing/tautological assertions, swallowed/broad exceptions, flaky/order-dependent tests, duplication, or magic values. Polyglot. DO NOT USE for direct edits: writing-mstest-tests owns supplied MSTest assertions/attributes/lifecycle; code-testing owns new tests. Exclude running tests, migration, assertion metrics (assertion-quality), raw .NET coverage collection (run-tests), non-.NET coverage collection/analysis (native tooling), project-wide .NET coverage/CRAP (coverage-analysis), named-target .NET CRAP (crap-score), behavioral/pseudo-mutation gaps (test-gap-analysis), test-mix/ happy-vs-error classification and trait distributions (test-tagging), or the testsmells.org catalog (test-smell-detection).

Testing & QA4.5K installs

filter-syntax

dotnet/skills

Reference-only filter syntax for VSTest and MTP with MSTest, NUnit, xUnit v3, and TUnit. Load only after the platform/framework is known and a consumer needs to create or translate a filter. Do not load for unfiltered runs or platform detection. Used by run-tests and mtp-hot-reload; never invoke directly.

Backend & APIs4.5K installs

dotnet-webapi

dotnet/skills

Guides creation and modification of ASP.NET Core Web API endpoints with correct HTTP semantics, OpenAPI metadata, and error handling. USE FOR: adding new API endpoints (controllers or minimal APIs), wiring up OpenAPI/Swagger, creating .http test files, setting up global error handling middleware. DO NOT USE FOR: general C coding style, EF Core data access or query optimization (use optimizing-ef-core-queries), frontend/Blazor work, gRPC services, or SignalR hubs.

Backend & APIs4.3K installs

Popular backend & apis skills

View category →

find-skills

vercel-labs/skills

Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.

OfficialBackend & APIs4.1M installs

entra-app-registration

microsoft/azure-skills

Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.

OfficialBackend & APIs566.7K installs

This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).

Backend & APIs514.8K installs

embedded-captions

heygen-com/hyperframes

Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.

Backend & APIs453.3K installs

entra-agent-id

microsoft/azure-skills

Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).

OfficialBackend & APIs336.6K installs

neon

neondatabase/agent-skills

Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.

Backend & APIs237.1K installs