Skip to content

v2.8.0

Choose a tag to compare

@github-actions github-actions released this 25 Jul 13:02
· 152 commits to main since this release

Added

  • Command.ConsoleEncoding() decodes a child's captured stdout and stderr with the local console encoding instead of UTF-8 — the one-line fix for a legacy Windows console program (ping, netstat, an old in-house CLI) whose non-ASCII output otherwise arrives as U+FFFD; it resolves this process's console output code page, or the system OEM code page when there is no console, and is a no-op off Windows. The same answer is available on its own as ConsoleEncoding.current () for a pipeline, a CliClient, or a single stream. The UTF-8 default is unchanged, and this adds no new package dependency.
  • Command.LaunchDetached() / Exec.detach launch a child outside all containment — no Job Object on Windows, its own setsid session on POSIX — for spawn-and-forget work that must outlive the caller (a self-updater, a restart-myself relaunch, a daemon handed to the OS); it returns a lightweight DetachedProcess (pid + start-time identity, no wait/stream/kill member), and every builder knob a detached child cannot honour (Pty, KillOnParentDeath, the timeouts, CancelOn, a feeder Stdin, KeepStdinOpen, the line handlers and tees, StreamBuffer, Retry) is refused with a typed ProcessError.Unsupported instead of being ignored.
  • PtySession drives an interactive program the way an expect script does: wait for a pattern (text or Regex) in the child's raw terminal output — including a prompt such as Password: that no line-based wait can see — with a per-pattern timeout, answer it through SendAsync/SendLineAsync, and read the whole exchange back from Transcript.
  • ProcessKit.Testing.FakeProcess.WithStdinOpen() keeps a fake's stdin open (like Command.KeepStdinOpen()), so a PtySession can be driven against the PTY double with no real process.
  • Command.WindowsRestrictedToken() runs a child under a restricted token (CreateRestrictedToken with DISABLE_MAX_PRIVILEGE), leaving it the caller's identity but no privilege beyond SeChangeNotifyPrivilege — the Windows counterpart of the Unix Uid/Gid drop, with a typed ProcessError.Unsupported on POSIX.
  • Command.WindowsIntegrityLevel(level) lowers a child's Windows mandatory integrity level (Medium/Low/Untrusted), so Windows' no-write-up policy denies it write access to anything labelled above that level; it composes with WindowsRestrictedToken and is likewise ProcessError.Unsupported on POSIX.
  • ProcessGroupOptions.WithUiRestrictions(...) / ResourceLimits.WithUiRestrictions(...) apply Windows Job Object UI restrictions to a contained tree — denying it the clipboard, desktop creation/switching, display and system parameters, the global atom table, and ExitWindows — with ProcessError.Unsupported off Windows rather than a silently unrestricted group.
  • ProcessGroupOptions.WithCpuAffinity(cores) / ResourceLimits.WithCpuAffinity(cores) pin a contained tree to specific CPU cores — a Windows Job Object affinity mask, a Linux cgroup v2 cpuset.cpus — so a noisy child can be kept off latency-critical cores; it is live-updatable through UpdateLimits and fails with a typed ProcessError.ResourceLimit where no whole-tree pin can be enforced (macOS/BSD, Linux without cgroup v2 or without the cpuset controller, or a core index a Windows affinity mask cannot express) rather than silently running everywhere.

Fixed

  • Fixed the hardening guide's C# sample disposing a RunningProcess with using, which does not compile — the handle is IAsyncDisposable, so the sample now reads await using.
  • Fixed latent masking of the original read/write stream error when cancellation interrupted a tee-sink flush.
  • PTY streams now reject invalid buffer ranges before native I/O and fail safely when a write makes no progress.
  • Supervision stop lifecycle now completes cleanly after a session finishes.