Skip to content

Improve handling of CTRL+C when dnx is used on Windows #49633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 8, 2025

Conversation

dsplaisted
Copy link
Member

@dsplaisted dsplaisted commented Jul 2, 2025

Fixes #49623

There is apparently no way to avoid the "Terminate batch job" behavior when running a batch script with cmd.exe (see microsoft/terminal#217). We could add an .exe shim instead of a .cmd file, but a NativeAOT executable to accomplish this would add about 1.5 MB to the payload.

So instead, this PR adds a dnx.ps1 script in addition to dnx.cmd. This fixes the behavior for people using PowerShell as their command interpreter. It doesn't fix the issue for people using cmd. It looks like Yarn went with this option.

Copilot prompt:

Add code to #file:'dnx.cs' to launch a new process.  It should launch the dotnet executable in the same directory as the current program.  It should pass "dnx" as the first argument, and then add all the other arguments that were passed to the current program.
Use top level statements and argument escaper
@dsplaisted dsplaisted requested review from Copilot and baronfel July 2, 2025 13:10
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR replaces the Windows batch-based dnx script with a native AOT executable shim to avoid the “Terminate batch job” prompt when pressing CTRL+C in cmd.exe. On non-Windows platforms it continues to use the existing shell script.

  • Renames MSBuild target LayoutDnxScriptLayoutDnxShim and copies the AOT shim on Windows.
  • Adds a new dnx project (NativeAOT shim) and includes it in the solution/redist.
  • Implements dnx.cs shim logic and updates documentation.

Reviewed Changes

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

Show a summary per file
File Description
src/Layout/redist/targets/GenerateInstallerLayout.targets Renamed script target to shim and updated copy logic.
src/Layout/redist/redist.csproj Added reference to new dnx shim project.
src/Layout/dnx/dnx.csproj New project for AOT shim with publish settings.
src/Layout/dnx/dnx.cs Shim entrypoint forwarding args to dotnet dnx.
src/Layout/dnx/README.md Documentation for shim rationale and behavior.
sdk.slnx Included dnx shim project in solution folder.
Comments suppressed due to low confidence (1)

src/Layout/dnx/dnx.cs:1

  • This new shim changes signal propagation and argument forwarding; please add automated tests to verify correct CTRL+C behavior on Windows and ensure arguments are passed intact.
// Licensed to the .NET Foundation under one or more agreements.

@@ -0,0 +1,6 @@
# dnx.ps1
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't use PowerShell much and I just generated this script by asking copilot to translate the batch script to PowerShell. So I'd appreciate review of the script from someone more familiar with PowerShell.

@dsplaisted dsplaisted requested a review from a team July 4, 2025 17:24
@joeloff
Copy link
Member

joeloff commented Jul 6, 2025

Since these will be shipping, shouldn't we include the MIT license header in these files?

@joeloff
Copy link
Member

joeloff commented Jul 6, 2025

Do we need to add the .ps1 to the list of files to be signed?

@@ -0,0 +1,6 @@
# dnx.ps1
Copy link
Member

Choose a reason for hiding this comment

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

Should we add a #Requires -Version 6.0
to make sure powershell supports Split-Path?

@Args was also added in 3.0 (2012 powershell).

Copy link
Member Author

Choose a reason for hiding this comment

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

It looks like Split-Path has been around since PowerShell 1.0. We don't want to require version 6 of PowerShell, I think that's the .NET Core version that you have to install separately. I think we want this script to work on the PowerShell that's included with Windows. As far as I can tell it does. The lowest version of Windows we support is Server 2012 which has PowerShell 3, so I think we're good.

@@ -0,0 +1,6 @@
# dnx.ps1
# PowerShell script to launch dotnet.exe with 'dnx' and all passed arguments
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
Copy link
Member

Choose a reason for hiding this comment

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

Users will need to select the ps1 script instead of the cmd, right? Is it ok that DnxShimSource can contain 2 possible shim sources now, and is there any logic that might need updating because of this?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you're running PowerShell, then the ps1 script will take precedence over the .cmd script. So either way you just type dnx, and from PowerShell you'll get the ps1 script with improved CTRL+C handling, and from a cmd shell you'll get the .cmd script and the extra CTRL+C termination confirmation.

The only use of DnxShimSource is in GenerateInstallerLayout.targets and it has been updated to handle the items appropriately.

Copy link
Member

@nagilson nagilson left a comment

Choose a reason for hiding this comment

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

Thanks for this! I think it looks good but there are some important comments (esp signing) included within that I think should be considered.

Co-authored-by: Jacques Eloff <joeloff@users.noreply.github.com>
@dsplaisted dsplaisted enabled auto-merge July 8, 2025 15:38
@dsplaisted dsplaisted merged commit a354e47 into dotnet:main Jul 8, 2025
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ctrl+C on a dnx-invoked tool shows an unescapable Windows Batch termination dialog
4 participants