[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DYRT8MS8HJMFSRZMD36B3G":3,"skill-same:01M6DYRT8MS8HJMFSRZMD36B3G":84},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":48,"linkOnly":49,"markdownContent":50,"markdownBody":51,"frontMatter":52,"refName":54,"commitSha":55,"skillDirectory":56,"forksCount":57,"repositoryHtmlUrl":58,"repositoryHomepageUrl":59,"ownerHtmlUrl":60,"ownerBlogUrl":61,"ownerDescription":62,"updatedAt":63,"install":64,"resources":77},"01M6DYRT8MS8HJMFSRZMD36B3G","process-api-net11",null,"Provides guidance on the new System.Diagnostics.Process APIs introduced in .NET 11: Process.Run, Process.RunAndCaptureText, Process.StartAndForget, Process.ReadAllText\u002FBytes\u002FLines, 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.","managedcode\u002Fdotnet-skills","managedcode","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F78253589?v=4","01M6DYDJR3EG8KB5G4PC65XCTT","Managed Code","01M6DYDJX0ZT432N04NYJW89DN",511,"MIT","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FPlatform\u002FOfficial-DotNet-Dotnet11\u002Fskills\u002Fprocess-api-net11\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47],"api","process","process api net11","later","new","for","targeting","usage","output","processes","basic","do","diagnostics","guidance","use","system","applications","start","run","2026-11-10 10:12:30",false,"---\nname: process-api-net11\ndescription: >\n  Provides guidance on the new System.Diagnostics.Process APIs introduced in .NET 11:\n  Process.Run, Process.RunAndCaptureText, Process.StartAndForget, Process.ReadAllText\u002FBytes\u002FLines,\n  KillOnParentExit, InheritedHandles, and StartDetached.\n  USE FOR: starting, orchestrating, or capturing output from external processes in applications targeting net11.0 or later.\n  DO NOT USE FOR: applications targeting .NET 10 or earlier, or basic pre-.NET 11 Process.Start usage without new APIs.\nlicense: MIT\n---\n\n# Process API Improvements — .NET 11\n\nNew 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.\n\n## When to Use\n\n- Running or orchestrating external processes in a .NET 11 (or later) project.\n- Needing to start a process, wait for it to exit, and capture its output\u002Ferror streams without risking deadlocks (`Process.RunAndCaptureText[Async]`).\n- Wanting to ensure child processes are automatically terminated when the parent process exits (`KillOnParentExit`).\n- Requiring lightweight, low-overhead process creation via `SafeProcessHandle` on supported platforms.\n- Requiring fine-grained control over handle inheritance (`InheritedHandles`) or starting detached processes (`StartDetached`).\n\n## When Not to Use\n\n- The project targets .NET 10 or earlier — these APIs are not available before .NET 11.\n- The default `Process.Start()` is sufficient and does not require output capturing or advanced lifecycle rules.\n\n## Target Framework\n\n```xml\n\u003CTargetFramework>net11.0\u003C\u002FTargetFramework>\n```\n\n## New APIs\n\n### Types\n\nBefore using the new convenience methods, note the following types. Use the framework types directly:\n\n| Type | Kind | Read-only properties |\n|------|------|----------------------|\n| `ProcessExitStatus` | Sealed class | `int ExitCode`, `bool Canceled`, `PosixSignal? Signal` |\n| `ProcessTextOutput` | Sealed class | `ProcessExitStatus ExitStatus`, `string StandardOutput`, `string StandardError`, `int ProcessId` |\n| `ProcessOutputLine` | Readonly struct | `string Content`, `bool StandardError` |\n\n`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.\n\n### High-Level Convenience APIs\n\n#### Static Methods\n\nThe `ProcessStartInfo` overloads below require `UseShellExecute = false`, which is the default for .NET.\n\n##### `Process.Run` \u002F `Process.RunAsync`\nStarts 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.\n```csharp\npublic static ProcessExitStatus Run(string fileName, IEnumerable\u003Cstring>? arguments = null, bool silent = false, TimeSpan? timeout = null)\npublic static Task\u003CProcessExitStatus> RunAsync(string fileName, IEnumerable\u003Cstring>? arguments = null, bool silent = false, CancellationToken cancellationToken = default)\npublic static ProcessExitStatus Run(ProcessStartInfo startInfo, TimeSpan? timeout = null)\npublic static Task\u003CProcessExitStatus> RunAsync(ProcessStartInfo startInfo, CancellationToken cancellationToken = default)\n```\n\n##### `Process.RunAndCaptureText` \u002F `Process.RunAndCaptureTextAsync`\nStarts 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.\n\nWhen 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).\n```csharp\npublic static ProcessTextOutput RunAndCaptureText(string fileName, IEnumerable\u003Cstring>? arguments = null, TimeSpan? timeout = null)\npublic static Task\u003CProcessTextOutput> RunAndCaptureTextAsync(string fileName, IEnumerable\u003Cstring>? arguments = null, CancellationToken cancellationToken = default)\npublic static ProcessTextOutput RunAndCaptureText(ProcessStartInfo startInfo, TimeSpan? timeout = null)\npublic static Task\u003CProcessTextOutput> RunAndCaptureTextAsync(ProcessStartInfo startInfo, CancellationToken cancellationToken = default)\n```\n\n##### `Process.StartAndForget`\nThere 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.\n\nTo 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.\n\n`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.\n```csharp\npublic static int StartAndForget(string fileName, IEnumerable\u003Cstring>? arguments = null)\npublic static int StartAndForget(ProcessStartInfo startInfo)\n```\n\n#### Instance Methods\nThese methods are called on a `Process` instance to directly read stdout and stderr, guaranteeing no OS pipe buffer overflow deadlocks.\n\n*Note: Calling these methods requires `RedirectStandardOutput = true` and `RedirectStandardError = true` on the `ProcessStartInfo` passed to `Process.Start`.*\n\n```csharp\npublic (string StandardOutput, string StandardError) ReadAllText(TimeSpan? timeout = null)\npublic Task\u003C(string StandardOutput, string StandardError)> ReadAllTextAsync(CancellationToken cancellationToken = default)\npublic (byte[] StandardOutput, byte[] StandardError) ReadAllBytes(TimeSpan? timeout = null)\npublic Task\u003C(byte[] StandardOutput, byte[] StandardError)> ReadAllBytesAsync(CancellationToken cancellationToken = default)\npublic IEnumerable\u003CProcessOutputLine> ReadAllLines(TimeSpan? timeout = null)\npublic IAsyncEnumerable\u003CProcessOutputLine> ReadAllLinesAsync(CancellationToken cancellationToken = default)\n```\n\nExample of deconstructing the tuple return:\n```csharp\nvar (stdout, stderr) = await process.ReadAllTextAsync();\n```\n\n### ProcessStartInfo Properties\n\n#### `KillOnParentExit`\nEnsures 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.\n```csharp\npublic bool KillOnParentExit { get; set; }\n```\n\nIn 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.\n`KillOnParentExit` requires `UseShellExecute = false`.\n\n#### `InheritedHandles`\nProvides precise control over which handles (file descriptors) are inherited by the child process, preventing accidental resource leaks.\n- Standard handles (`stdin`, `stdout`, `stderr`) are always included (no need to add them to the list).\n- Setting the list to an empty list means only standard handles get inherited.\n- Only `SafeFileHandle` and `SafePipeHandle` instances are allowed as of today.\n- No global lock is used when spawning new processes on Windows (important for tuning projects that spawn multiple processes in parallel).\n- 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.\n- Do not enable inheritance on the handles before passing them; other process-start APIs could then inherit them unintentionally.\n- On Unix systems without native handle-inheritance control, setting this property can severely reduce process-start performance.\n- A non-null list requires `UseShellExecute = false` and cannot be combined with a non-empty `UserName`.\n```csharp\npublic IList\u003CSafeHandle>? InheritedHandles { get; set; }\n```\n\n#### `StartDetached`\nStarts the process detached from the parent's terminal or job session, ensuring it survives the parent's exit.\n```csharp\npublic bool StartDetached { get; set; }\n```\n\n`StartDetached` requires `UseShellExecute = false`.\n\n---\n\n## Examples\n\n### 1. One-Line Run and Capture Output\n\nRun 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:\n\n```csharp\nusing System;\nusing System.Diagnostics;\n\n\u002F\u002F Run 'git status' and capture output\nProcessTextOutput result = Process.RunAndCaptureText(\"git\", [\"status\"]);\n\nif (result.ExitStatus.ExitCode == 0)\n{\n    Console.WriteLine($\"Git Output: {result.StandardOutput}\");\n}\nelse\n{\n    Console.WriteLine($\"Failed with exit code: {result.ExitStatus.ExitCode}\");\n    Console.WriteLine($\"Error: {result.StandardError}\");\n}\n```\n\n### 2. Auto-Killing Child Processes on Parent Exit\n\nOn 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:\n\n```csharp\nusing System;\nusing System.Diagnostics;\n\nProcessStartInfo startInfo = new(\"dotnet\", [\"run\", \"--project\", \"BackgroundWorker.csproj\"]);\n\nif (OperatingSystem.IsWindows() || OperatingSystem.IsLinux() || OperatingSystem.IsAndroid())\n{\n    startInfo.KillOnParentExit = true;\n}\nelse\n{\n    throw new PlatformNotSupportedException(\"This example requires Windows, Linux, or Android.\");\n}\n\nusing Process process = Process.Start(startInfo)!;\n\u002F\u002F The background worker is now tied to this process's lifecycle\n```\n\n### 3. Read All Lines From Output\n\nStart a process and read its output lines safely:\n\n```csharp\nusing System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nProcessStartInfo startInfo = new(\"ping\", [\"127.0.0.1\"])\n{\n    RedirectStandardOutput = true,\n    RedirectStandardError = true\n};\n\nusing Process process = Process.Start(startInfo)!;\n\u002F\u002F Read all output lines safely and asynchronously\nawait foreach (ProcessOutputLine line in process.ReadAllLinesAsync())\n{\n    string prefix = line.StandardError ? \"[Err]\" : \"[Out]\";\n    Console.WriteLine($\"{prefix} > {line.Content}\");\n}\n```\n\n### 4. Read Entire Output Deadlock-Free (Tuple Return)\n\nStart a process with custom `ProcessStartInfo` and read both stdout and stderr into a deconstructed tuple without buffer deadlocks:\n\n```csharp\nusing System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nProcessStartInfo startInfo = new(\"git\", [\"diff\"])\n{\n    RedirectStandardOutput = true,\n    RedirectStandardError = true\n};\n\nusing Process process = Process.Start(startInfo)!;\nvar (stdout, stderr) = await process.ReadAllTextAsync();\n\nConsole.WriteLine($\"Diff output: {stdout}\");\n```\n\n### 5. Start and Forget (Fire & Forget)\n\nLaunch a helper executable without holding onto system handle structures:\n\n```csharp\nusing System;\nusing System.Diagnostics;\n\n\u002F\u002F Fire and forget, getting back only the process ID\nint pid = Process.StartAndForget(\"notepad.exe\");\nConsole.WriteLine($\"Notepad started with PID: {pid}\");\n```\n","# Process API Improvements — .NET 11\n\nNew 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.\n\n## When to Use\n\n- Running or orchestrating external processes in a .NET 11 (or later) project.\n- Needing to start a process, wait for it to exit, and capture its output\u002Ferror streams without risking deadlocks (`Process.RunAndCaptureText[Async]`).\n- Wanting to ensure child processes are automatically terminated when the parent process exits (`KillOnParentExit`).\n- Requiring lightweight, low-overhead process creation via `SafeProcessHandle` on supported platforms.\n- Requiring fine-grained control over handle inheritance (`InheritedHandles`) or starting detached processes (`StartDetached`).\n\n## When Not to Use\n\n- The project targets .NET 10 or earlier — these APIs are not available before .NET 11.\n- The default `Process.Start()` is sufficient and does not require output capturing or advanced lifecycle rules.\n\n## Target Framework\n\n```xml\n\u003CTargetFramework>net11.0\u003C\u002FTargetFramework>\n```\n\n## New APIs\n\n### Types\n\nBefore using the new convenience methods, note the following types. Use the framework types directly:\n\n| Type | Kind | Read-only properties |\n|------|------|----------------------|\n| `ProcessExitStatus` | Sealed class | `int ExitCode`, `bool Canceled`, `PosixSignal? Signal` |\n| `ProcessTextOutput` | Sealed class | `ProcessExitStatus ExitStatus`, `string StandardOutput`, `string StandardError`, `int ProcessId` |\n| `ProcessOutputLine` | Readonly struct | `string Content`, `bool StandardError` |\n\n`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.\n\n### High-Level Convenience APIs\n\n#### Static Methods\n\nThe `ProcessStartInfo` overloads below require `UseShellExecute = false`, which is the default for .NET.\n\n##### `Process.Run` \u002F `Process.RunAsync`\nStarts 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.\n```csharp\npublic static ProcessExitStatus Run(string fileName, IEnumerable\u003Cstring>? arguments = null, bool silent = false, TimeSpan? timeout = null)\npublic static Task\u003CProcessExitStatus> RunAsync(string fileName, IEnumerable\u003Cstring>? arguments = null, bool silent = false, CancellationToken cancellationToken = default)\npublic static ProcessExitStatus Run(ProcessStartInfo startInfo, TimeSpan? timeout = null)\npublic static Task\u003CProcessExitStatus> RunAsync(ProcessStartInfo startInfo, CancellationToken cancellationToken = default)\n```\n\n##### `Process.RunAndCaptureText` \u002F `Process.RunAndCaptureTextAsync`\nStarts 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.\n\nWhen 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).\n```csharp\npublic static ProcessTextOutput RunAndCaptureText(string fileName, IEnumerable\u003Cstring>? arguments = null, TimeSpan? timeout = null)\npublic static Task\u003CProcessTextOutput> RunAndCaptureTextAsync(string fileName, IEnumerable\u003Cstring>? arguments = null, CancellationToken cancellationToken = default)\npublic static ProcessTextOutput RunAndCaptureText(ProcessStartInfo startInfo, TimeSpan? timeout = null)\npublic static Task\u003CProcessTextOutput> RunAndCaptureTextAsync(ProcessStartInfo startInfo, CancellationToken cancellationToken = default)\n```\n\n##### `Process.StartAndForget`\nThere 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.\n\nTo 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.\n\n`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.\n```csharp\npublic static int StartAndForget(string fileName, IEnumerable\u003Cstring>? arguments = null)\npublic static int StartAndForget(ProcessStartInfo startInfo)\n```\n\n#### Instance Methods\nThese methods are called on a `Process` instance to directly read stdout and stderr, guaranteeing no OS pipe buffer overflow deadlocks.\n\n*Note: Calling these methods requires `RedirectStandardOutput = true` and `RedirectStandardError = true` on the `ProcessStartInfo` passed to `Process.Start`.*\n\n```csharp\npublic (string StandardOutput, string StandardError) ReadAllText(TimeSpan? timeout = null)\npublic Task\u003C(string StandardOutput, string StandardError)> ReadAllTextAsync(CancellationToken cancellationToken = default)\npublic (byte[] StandardOutput, byte[] StandardError) ReadAllBytes(TimeSpan? timeout = null)\npublic Task\u003C(byte[] StandardOutput, byte[] StandardError)> ReadAllBytesAsync(CancellationToken cancellationToken = default)\npublic IEnumerable\u003CProcessOutputLine> ReadAllLines(TimeSpan? timeout = null)\npublic IAsyncEnumerable\u003CProcessOutputLine> ReadAllLinesAsync(CancellationToken cancellationToken = default)\n```\n\nExample of deconstructing the tuple return:\n```csharp\nvar (stdout, stderr) = await process.ReadAllTextAsync();\n```\n\n### ProcessStartInfo Properties\n\n#### `KillOnParentExit`\nEnsures 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.\n```csharp\npublic bool KillOnParentExit { get; set; }\n```\n\nIn 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.\n`KillOnParentExit` requires `UseShellExecute = false`.\n\n#### `InheritedHandles`\nProvides precise control over which handles (file descriptors) are inherited by the child process, preventing accidental resource leaks.\n- Standard handles (`stdin`, `stdout`, `stderr`) are always included (no need to add them to the list).\n- Setting the list to an empty list means only standard handles get inherited.\n- Only `SafeFileHandle` and `SafePipeHandle` instances are allowed as of today.\n- No global lock is used when spawning new processes on Windows (important for tuning projects that spawn multiple processes in parallel).\n- 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.\n- Do not enable inheritance on the handles before passing them; other process-start APIs could then inherit them unintentionally.\n- On Unix systems without native handle-inheritance control, setting this property can severely reduce process-start performance.\n- A non-null list requires `UseShellExecute = false` and cannot be combined with a non-empty `UserName`.\n```csharp\npublic IList\u003CSafeHandle>? InheritedHandles { get; set; }\n```\n\n#### `StartDetached`\nStarts the process detached from the parent's terminal or job session, ensuring it survives the parent's exit.\n```csharp\npublic bool StartDetached { get; set; }\n```\n\n`StartDetached` requires `UseShellExecute = false`.\n\n---\n\n## Examples\n\n### 1. One-Line Run and Capture Output\n\nRun 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:\n\n```csharp\nusing System;\nusing System.Diagnostics;\n\n\u002F\u002F Run 'git status' and capture output\nProcessTextOutput result = Process.RunAndCaptureText(\"git\", [\"status\"]);\n\nif (result.ExitStatus.ExitCode == 0)\n{\n    Console.WriteLine($\"Git Output: {result.StandardOutput}\");\n}\nelse\n{\n    Console.WriteLine($\"Failed with exit code: {result.ExitStatus.ExitCode}\");\n    Console.WriteLine($\"Error: {result.StandardError}\");\n}\n```\n\n### 2. Auto-Killing Child Processes on Parent Exit\n\nOn 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:\n\n```csharp\nusing System;\nusing System.Diagnostics;\n\nProcessStartInfo startInfo = new(\"dotnet\", [\"run\", \"--project\", \"BackgroundWorker.csproj\"]);\n\nif (OperatingSystem.IsWindows() || OperatingSystem.IsLinux() || OperatingSystem.IsAndroid())\n{\n    startInfo.KillOnParentExit = true;\n}\nelse\n{\n    throw new PlatformNotSupportedException(\"This example requires Windows, Linux, or Android.\");\n}\n\nusing Process process = Process.Start(startInfo)!;\n\u002F\u002F The background worker is now tied to this process's lifecycle\n```\n\n### 3. Read All Lines From Output\n\nStart a process and read its output lines safely:\n\n```csharp\nusing System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nProcessStartInfo startInfo = new(\"ping\", [\"127.0.0.1\"])\n{\n    RedirectStandardOutput = true,\n    RedirectStandardError = true\n};\n\nusing Process process = Process.Start(startInfo)!;\n\u002F\u002F Read all output lines safely and asynchronously\nawait foreach (ProcessOutputLine line in process.ReadAllLinesAsync())\n{\n    string prefix = line.StandardError ? \"[Err]\" : \"[Out]\";\n    Console.WriteLine($\"{prefix} > {line.Content}\");\n}\n```\n\n### 4. Read Entire Output Deadlock-Free (Tuple Return)\n\nStart a process with custom `ProcessStartInfo` and read both stdout and stderr into a deconstructed tuple without buffer deadlocks:\n\n```csharp\nusing System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nProcessStartInfo startInfo = new(\"git\", [\"diff\"])\n{\n    RedirectStandardOutput = true,\n    RedirectStandardError = true\n};\n\nusing Process process = Process.Start(startInfo)!;\nvar (stdout, stderr) = await process.ReadAllTextAsync();\n\nConsole.WriteLine($\"Diff output: {stdout}\");\n```\n\n### 5. Start and Forget (Fire & Forget)\n\nLaunch a helper executable without holding onto system handle structures:\n\n```csharp\nusing System;\nusing System.Diagnostics;\n\n\u002F\u002F Fire and forget, getting back only the process ID\nint pid = Process.StartAndForget(\"notepad.exe\");\nConsole.WriteLine($\"Notepad started with PID: {pid}\");\n```\n",{"name":5,"license":15,"description":53},"Provides guidance on the new System.Diagnostics.Process APIs introduced in .NET 11: Process.Run, Process.RunAndCaptureText, Process.StartAndForget, Process.ReadAllText\u002FBytes\u002FLines, 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.\n","main","497cc9aba79a931ac6fb8d36a48cc22fe3d6d74b","catalog\u002FPlatform\u002FOfficial-DotNet-Dotnet11\u002Fskills\u002Fprocess-api-net11",41,"https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills","https:\u002F\u002Fskills.managed-code.com","https:\u002F\u002Fgithub.com\u002Fmanagedcode","https:\u002F\u002Fwww.managed-code.com","Open Source Community for .NET Developers: Reliable, Actively Maintained, and Community-Driven. Made in Ukraine 🇺🇦 with ❤️","2026-11-10 19:58:06",{"source":8,"skillName":5,"commands":65,"prompt":75,"zipAvailable":76},[66,69,72],{"tool":67,"command":68},"npx","npx skills add managedcode\u002Fdotnet-skills --skill process-api-net11",{"tool":70,"command":71},"bunx","bunx skills add managedcode\u002Fdotnet-skills --skill process-api-net11",{"tool":73,"command":74},"pnpm","pnpm dlx skills add managedcode\u002Fdotnet-skills --skill process-api-net11","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FPlatform\u002FOfficial-DotNet-Dotnet11\u002Fskills\u002Fprocess-api-net11\u002FSKILL.md",true,[78],{"path":79,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":82,"sourceHtmlUrl":83},"manifest.json","REFERENCE","参考文档",109,"https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FPlatform\u002FOfficial-DotNet-Dotnet11\u002Fskills\u002Fprocess-api-net11\u002Fmanifest.json",[85,112,136,165,175,198],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":93,"publishedAt":48},"01M6DYQE1Y9FHAQHEDTVFQ3447","xtwitter-scraper","Use XTwitterScraper when a .NET application needs typed access to Xquik's X automation REST API for tweet search, user lookup, posting workflows, extraction jobs, monitors, webhooks, or giveaway draws. USE FOR: integrating the XTwitterScraper NuGet package; reviewing Xquik API client usage; modeling API-key configuration, pagination, binary exports, raw responses, retries, and webhook\u002Fevent flows in .NET. DO NOT USE FOR: unrelated stacks; direct browser automation; generic social-media strategy; or code that does not call Xquik. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FLibraries\u002FXTwitterScraper\u002Fskills\u002Fxtwitter-scraper\u002FSKILL.md",[91,92],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},[94,95,96,47,97,98,99,100,29,101,102,103,104,105,106,107,108,109,110,111],"xtwitter scraper","browser automation","workflows","code","browser","search","repository","Media","api client","access","edit","unrelated","webhooks","files","social","commands","modeling","webhook",{"skillNo":113,"name":114,"nameZh":6,"description":115,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":124,"publishedAt":48},"01M6DYQ9S4PE1H6G8MCH9T21HR","sep","Use Sep for high-performance separated-value parsing and writing in .NET, including delimiter inference, explicit parser\u002Fwriter options, and low-allocation row\u002Fcolumn workflows. USE FOR: delimited data needs are performance-sensitive and allocation-aware; project needs explicit control over separator inference, escaping, trimming, and header behavior;. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fcatalog\u002FLibraries\u002FSep\u002Fskills\u002Fsep\u002FSKILL.md",[118,121],{"categoryNo":119,"categoryName":120,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":122,"categoryName":123,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000036","内容创作者",[114,125,126,96,127,47,100,128,129,130,104,131,105,107,40,132,133,134,109,135],"writing","performance","tasks","data","parsing","parser","context","writer","options","project","high-performance",{"skillNo":137,"name":138,"nameZh":6,"description":139,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":140,"categories":141,"keywords":142,"publishedAt":48},"01M6DZS2DNEPXCGGF6SSCW6G5V","webgpu-threejs-tsl","Comprehensive guide for developing WebGPU-enabled Three.js applications using TSL (Three.js Shading Language). Covers WebGPU renderer setup, TSL syntax and node materials, compute shaders, post-processing effects, and WGSL integration. Use this skill when working with Three.js WebGPU, TSL shaders, node materials, or GPU compute in Three.js.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fexternal-sources\u002Fupstreams\u002Fwebgpu-claude-skill\u002Fskills\u002Fwebgpu-threejs-tsl\u002FSKILL.md",[],[143,144,145,146,147,148,149,45,150,151,152,153,43,154,155,156,157,158,159,160,34,161,162,163,164],"webgpu","threejs","webgpu threejs tsl","setup","shaders","gpu","integration","js","node","syntax","guide","language","three","compute","post","processing","with","renderer","materials","wgsl","effects","when",{"skillNo":166,"name":167,"nameZh":6,"description":168,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":169,"categories":170,"keywords":171,"publishedAt":48},"01M6DZS0BQXW2B56A289XF1X76","roslynk","Use Roslynk for semantic inspection and edits of *.cs, *.razor and *.cshtml solution files.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fexternal-sources\u002Fupstreams\u002Froslynk\u002Fskills\u002Froslynk\u002FSKILL.md",[],[167,43,107,172,173,34,174],"semantic","razor","inspection",{"skillNo":176,"name":177,"nameZh":6,"description":178,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":179,"categories":180,"keywords":181,"publishedAt":48},"01M6DZRW6MEJCVW80K3S4XV60K","system-text-json-net11","Imperative guidance for the System.Text.Json APIs added in .NET 11: the built-in `JsonNamingPolicy.PascalCase` naming policy, and the strongly-typed generic `JsonSerializerOptions.GetTypeInfo` and `JsonSerializerOptions.TryGetTypeInfo` metadata accessors (generic overloads that return a typed `JsonTypeInfo`). USE ONLY when the user is targeting net11.0 or later and needs PascalCase JSON property or dictionary-key names without writing a custom naming policy, a strongly-typed generic `JsonTypeInfo` instead of the non-generic `JsonTypeInfo`, or a no-throw way to probe whether a type's serialization metadata is resolved. DO NOT USE when the target is earlier than net11.0, the requested behavior uses an established pre-net11 naming policy, or the user explicitly selected another JSON library.","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fexternal-sources\u002Fupstreams\u002Fdotnet-skills\u002Fplugins\u002Fdotnet11\u002Fskills\u002Fsystem-text-json-net11\u002FSKILL.md",[],[44,182,183,184,125,185,186,187,188,189,190,43,191,192,42,32,40,193,194,195,35,34,196,197,164],"json","text","system text json net11","policy","metadata","library","serialization","behavior","user","only","probe","type","dictionary","naming","custom","generic",{"skillNo":199,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":200,"categories":201,"keywords":204,"publishedAt":48},"01M6DZRRJP3S662NFSG1RSPQQ7","https:\u002F\u002Fgithub.com\u002Fmanagedcode\u002Fdotnet-skills\u002Fblob\u002Fmain\u002Fexternal-sources\u002Fupstreams\u002Fdotnet-skills\u002Fplugins\u002Fdotnet11\u002Fskills\u002Fprocess-api-net11\u002FSKILL.md",[202,203],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},[29,30,31,41,47,46,45,44,43,42,32,40,39,38,37,36,35,34,33]]