Skip to content

Throw when Unix has no shell opener - #132219

Draft
adamsitnik with Copilot wants to merge 3 commits into
mainfrom
copilot/cherry-pick-commits-and-add-test
Draft

Throw when Unix has no shell opener#132219
adamsitnik with Copilot wants to merge 3 commits into
mainfrom
copilot/cherry-pick-commits-and-add-test

Conversation

Copilot AI commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

main PR #128416

Description

  • Cherry-picks the contributor fix to throw Win32Exception(ERROR_NO_ASSOCIATION) when no Unix shell opener is available.
  • Adds a Linux RemoteExecutor regression test that clears PATH, ensuring the failure is deterministic.

Customer Impact

Callers receive the intended Win32 error instead of a downstream null-related failure.

Regression

No.

Testing

Adds focused coverage for the no-opener path.

Risk

Low. Limits behavior to the existing shell-execute fallback failure path.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

Note

This PR description was generated by AI/Copilot.

Neo-vortex and others added 2 commits August 12, 2026 15:59
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@adamsitnik adamsitnik left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot address my feedback

}

[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[PlatformSpecific(TestPlatforms.Linux)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot why is it specific to Linux? I would expect it to work on every Unix? Or even every platform?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated in 3d8797e: the test now runs on Linux and FreeBSD. I did not extend it to all Unix platforms because this specific failure mode depends on opener lookup via PATH; on platforms with fixed opener paths (for example macOS/OpenBSD), clearing PATH does not produce the same no-opener condition.

Note

This reply was generated by AI/Copilot.


private const int O_RDONLY = 0;
private const int O_WRONLY = 1;
private const int ERROR_NO_ASSOCIATION = 0x483;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot what stops us from using Interop.Errors.ERROR_NO_ASSOCIATION? Why do we need to create a copy of this value?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated in 3d8797e to use Interop.Errors.ERROR_NO_ASSOCIATION instead of a duplicated local constant. To make that available for the unix test target, I also included Common/Interop/Windows/Interop.Errors.cs in the unix test project item group.

Note

This reply was generated by AI/Copilot.

@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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates Unix UseShellExecute fallback behavior in System.Diagnostics.Process so that when no shell “open” utility is discoverable, it throws a consistent Win32Exception(ERROR_NO_ASSOCIATION) instead of failing later due to a null opener path. Adds a Linux regression test that makes the “no opener” condition deterministic by clearing PATH in a RemoteExecutor child process.

Changes:

  • Throw Win32Exception(Interop.Errors.ERROR_NO_ASSOCIATION) when Process.GetPathToOpenFile() returns null in the Unix shell-execute fallback.
  • Add a Linux RemoteExecutor test that clears PATH and asserts the native error code is ERROR_NO_ASSOCIATION.
  • Introduce a local test constant for ERROR_NO_ASSOCIATION to validate the thrown error code.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs Adds deterministic Linux regression coverage for the “no shell opener on PATH” scenario.
src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs Throws the intended ERROR_NO_ASSOCIATION when no opener utility is found, preventing downstream null-related failures.

Comment on lines 407 to 409
// use default program to open file/url
filename = Process.GetPathToOpenFile();
filename = Process.GetPathToOpenFile() ?? throw new Win32Exception(Interop.Errors.ERROR_NO_ASSOCIATION);
string[] openFileArgv = ProcessUtils.ParseArgv(startInfo, filename, ignoreArguments: true);
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 12, 2026 17:43

Copilot AI commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address my feedback

Addressed in 3d8797e.

Note

This reply was generated by AI/Copilot.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs:84

  • This test relies on clearing PATH to force Process.GetPathToOpenFile() to return null. On FreeBSD, GetPathToOpenFile() checks a fixed path (/usr/local/bin/open) rather than searching PATH, so the test can become environment-dependent/flaky (it will start the opener if it happens to be installed). Consider limiting the test to Linux (as described in the PR) or otherwise making the FreeBSD behavior deterministic.
        [PlatformSpecific(TestPlatforms.Linux | TestPlatforms.FreeBSD)]
        public void ProcessStart_UseShellExecute_OnUnix_ThrowsWhenNoOpenerOnPath()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants