Obsolete the command-string overloads - #45
Merged
Conversation
The overloads taking a single command string separate the executable from its arguments by splitting on the first space, so an executable path containing a space is split in the middle and the call fails. On Windows that covers the default install location of most software. Quoting does not help, because the split happens before any quote handling, leaving a filename with a leading quote and a truncated path. The string form is inherently ambiguous: no parse handles every combination of spaces and quotes without adopting a shell's full grammar, and a half-grammar moves the surprise rather than removing it. Deprecate the eleven affected overloads in favour of the argument-vector ones, which have no such ambiguity because the executable is passed separately. Tests that exercise the obsolete overloads keep calling them, since those overloads still have to work until they are removed; the suppression is scoped to exactly those tests rather than the file. The cancellation test used a command string only incidentally, so it moves to the argument-vector form instead. Fixes #41
matt-edmondson
force-pushed
the
feat/40-environment-variables
branch
from
August 19, 2026 10:43
f59f8a1 to
ed58449
Compare
matt-edmondson
force-pushed
the
chore/41-obsolete-string-overloads
branch
from
August 19, 2026 10:43
295a537 to
956659b
Compare
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Fixes #41.
Problem
The overloads taking a single
commandstring split on the first space to separate the executable from its arguments, so an executable path containing a space is split mid-path and the call fails withWin32Exception. On Windows that covers the default install location of most software:Quoting does not rescue it, because the split happens before any quote handling —
"C:\Programis what the filename becomes.Approach
Option 3 from the issue. The string form is inherently ambiguous: no parse handles every combination of spaces and quotes without adopting a shell's full grammar, and a half-grammar (handling only a leading quoted segment) moves the surprise rather than removing it. So all eleven command-string overloads are marked
[Obsolete], pointing at the argument-list overloads that already exist and avoid the whole class of problem.Behaviour is unchanged — the overloads still work exactly as before, they just warn.
Breaking-change note
Deliberate, and worth calling out: downstream consumers building with
TreatWarningsAsErrorswill fail to build on upgrade until they migrate. That is the intended force of this option rather than an oversight, but it ships as[minor], so it is worth being comfortable with that before merging.The README gains a migration table mapping each obsolete overload to its replacement, and every example now uses the argument-list form.
Suppression scope
Per the repo's rule on targeted suppressions:
#pragma warning disable CS0618region that ends after the last such test rather than covering the file.ExecuteAsyncShouldFailWhenArgumentWithSpacesIsPassedAsOneStringpins the very mis-split that motivates this change, so it carries its own one-line suppression with that justification.ExecuteAsyncShouldThrowWhenTokenIsAlreadyCancelledused a command string only incidentally, so it was migrated to the argument-list form rather than suppressed.No suppression was needed in the library itself — Roslyn does not report obsolete usage from within an obsolete member, so the synchronous overloads delegating to the asynchronous ones stay clean.
Testing
Full suite: 32 passed, 2 skipped (elevated tests self-skip to avoid a UAC prompt). Builds clean across all eight target frameworks.
🤖 Generated with Claude Code
https://claude.ai/code/session_01LwKTWcmxe5mh6DsLRj5NGQ