Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 13, 2025

Implementation Plan for Executable Launch Profile Support

  • Understand the Executable launch profile format from project-system documentation
  • Create ExecutableLaunchSettingsProvider with typed models and JSON deserialization
  • Create base LaunchSettingsModel with derived models for Project and Executable profiles
  • Add ProfileKind discriminator to enable type pattern matching
  • Register the Executable provider in LaunchSettingsManager
  • Expose SupportedProfileTypes from LaunchSettingsManager
  • Update default profile detection in LaunchSettingsProfile.cs to use supported types array
  • Refactor RunCommand to use pattern matching with ProfileKind discriminator
  • Split execution logic into ExecuteWithProjectProfile and ExecuteWithExecutableProfile
  • Create test assets with Executable launch profiles
  • Add tests for Executable launch profile loading and execution
  • Test the implementation manually
  • Address code review feedback
  • Use localized strings for error messages
  • Refactor argument handling to improve clarity
  • Extract common command execution logic to reduce duplication
  • Add comprehensive tests for launch profile settings application

Changes Made:

Architecture

  1. Created base LaunchSettingsModel with ProfileKind discriminator enum
  2. Derived ProjectLaunchSettingsModel and ExecutableLaunchSettingsModel from base
  3. Created JSON binding models (ProjectLaunchProfileJson, ExecutableLaunchProfileJson)
  4. Updated all providers to use JsonSerializer.Deserialize instead of manual JSON traversal
  5. Exposed SupportedProfileTypes property from LaunchSettingsManager

Execution Flow

  1. Updated RunCommand.Execute() to use pattern matching: if (launchSettings is ExecutableLaunchSettingsModel execSettings)
  2. Split into ExecuteWithProjectProfile() and ExecuteWithExecutableProfile() methods
  3. Extracted common execution logic into ExecuteCommand() method to reduce duplication
  4. Updated all method signatures throughout codebase to use base LaunchSettingsModel type
  5. Used localized error strings for unknown profile types
  6. Refactored argument building to properly escape ApplicationArgs before combining with CommandLineArgs

dotnet-watch Support

  1. Updated LaunchSettingsProfile.cs to use array of supported types with documentation comment
  2. Improved error logging to show all supported types

Testing

  1. Added 3 initial tests for basic executable profile functionality
  2. Added 4 comprehensive tests verifying:
    • Environment variable application from launch profile
    • Working directory settings application
    • Command line argument combination (profile + command line)
    • Environment variable expansion in executable paths
  3. Created test assets:
    • AppForExecutableProfile: Helper app to verify environment and arguments
    • AppWithDetailedExecutableProfile: Test project with various executable profiles

Tests:

✅ All 6 Executable profile tests pass (3 basic + 4 comprehensive)
✅ All 11 existing launch settings tests pass
✅ Manual testing confirmed functionality

<issue_title>Allow dotnet run to use launch profiles with commandName: Executable</issue_title>
><issue_description>This is a disparity between the dotnet CLI and Visual Studio.
> I was trying to use the dotnet CLI for running a 3rd party application, specified in launchSettings.json, which my project is a plugin for, however, the "Executable" type is not supported. It does however work with Visual studio.
>
> ### Describe the solution you'd like
> Allow dotnet run to launch the 3rd party application and possibly take control of it's life cycle in some way so that hot reload can work with dotnet watch.
></issue_description>
>
><agent_instructions>Make sure to add tests for the launch profile loading, and to review my comments in the thread before implementation.</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
>
><comment_new>@marcpopMSFT
> Triage: VS has a few different launch targets we don't support currently. There is a similar ask for container support. Moving to backlog as we collect more feedback.</comment_new>
><comment_new>@baronfel
> No workaround as of yet, but the Project System team has docs about their profiles and how they are supported here. We'd need someone to contribute the handling for the "executable" type, as we're working on other things at this time. If you wanted to do that, we'd gladly help you get a PR merged!</comment_new>
><comment_new>@baronfel
> For executable profile support, there are two locations that would need to be updated:
>
> * the provider that actually applies the launch settings values to the executable to run: src/Cli/dotnet/Commands/Run/LaunchSettings/LaunchSettingsManager.cs
> * the 'default profile' detection logic: src/BuiltInTools/dotnet-watch/Process/LaunchSettingsProfile.cs
> * this default-profile detection logic should probably look for the first profile that is a type supported by the LaunchSettingsManager, if we're being honest. That'd make future profiles only require changing the one location
> </comment_new>
>
>

Original prompt

This section details on the original issue you should resolve

<issue_title>Allow dotnet run to use launch profiles with commandName: Executable</issue_title>
<issue_description>This is a disparity between the dotnet CLI and Visual Studio.
I was trying to use the dotnet CLI for running a 3rd party application, specified in launchSettings.json, which my project is a plugin for, however, the "Executable" type is not supported. It does however work with Visual studio.

Describe the solution you'd like

Allow dotnet run to launch the 3rd party application and possibly take control of it's life cycle in some way so that hot reload can work with dotnet watch.
</issue_description>

<agent_instructions>Make sure to add tests for the launch profile loading, and to review my comments in the thread before implementation.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@marcpopMSFT Triage: VS has a few different launch targets we don't support currently. There is a similar ask for container support. Moving to backlog as we collect more feedback. @baronfel No workaround as of yet, but the Project System team has docs about their profiles and how they are supported [here](https://github.com/dotnet/project-system/blob/271b27699dc4c4538f8cc95c3b5b7008f657b18c/docs/launch-profiles.md). We'd need someone to contribute the handling for the "executable" type, as we're working on other things at this time. If you wanted to do that, we'd gladly help you get a PR merged! @baronfel For `executable` profile support, there are two locations that would need to be updated:

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
Copy link
Member

@baronfel baronfel left a comment

Choose a reason for hiding this comment

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

@copilot Good initial attempt, but we can clean this up some. Please address my review comments.

Copilot AI changed the title [WIP] Allow dotnet run to use launch profiles for Executable Add Executable launch profile support to dotnet run and dotnet watch Nov 13, 2025
Copilot AI requested a review from baronfel November 13, 2025 22:53
Copilot finished work on behalf of baronfel November 13, 2025 22:53
- Created base LaunchSettingsModel with ProfileKind discriminator
- Derived ProjectLaunchSettingsModel and ExecutableLaunchSettingsModel
- Added JSON binding models for deserialization
- Updated providers to use JsonSerializer.Deserialize instead of manual traversal
- Exposed SupportedProfileTypes from LaunchSettingsManager
- Updated LaunchSettingsProfile.cs to use array of supported types with comment
- Updated RunCommand to use pattern matching on ProfileKind
- Split Execute method into ExecuteWithProjectProfile and ExecuteWithExecutableProfile
- Updated all method signatures to use base LaunchSettingsModel type

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
@baronfel baronfel self-requested a review November 14, 2025 00:38
Changed hardcoded error message to use CliCommandStrings.LaunchProfileHandlerCannotBeLocated for proper localization support.

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
Copilot finished work on behalf of baronfel November 14, 2025 00:46
Simplified argument building logic to make it clearer that ApplicationArgs are properly escaped before being combined with launchSettings.CommandLineArgs. Added comments explaining that CommandLineArgs from JSON cannot be reliably parsed into tokens.

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
}

private static ProjectLaunchSettingsModel? TryGetLaunchProfileSettings(string projectDirectory, string projectNameWithoutExtension, string appDesignerFolder, BuildOptions buildOptions, string? profileName)
private static LaunchSettingsModel? TryGetLaunchProfileSettings(string projectDirectory, string projectNameWithoutExtension, string appDesignerFolder, BuildOptions buildOptions, string? profileName)
Copy link
Member

Choose a reason for hiding this comment

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

@dotnet/dotnet-testing if we expand the 'launch settings' handlers that are known, how should the testing experience react? does test support launch settings profiles today?

@baronfel baronfel marked this pull request as ready for review November 14, 2025 03:02
@baronfel baronfel requested review from a team and tmat November 14, 2025 03:03
.WorkingDirectory(workingDirectory);

// Apply environment variables from launch profile
ApplyLaunchSettingsProfileToCommand(command, launchSettings);
Copy link
Member

Choose a reason for hiding this comment

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

Seems like starting from here the code is the same as ExecuteWithProjectProfile.

Might be better to refactor these methods to methods that return a command based on the profile and then common code that sets env variables, sends telemetry and executes the command.

Copy link
Member

Choose a reason for hiding this comment

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

@copilot do this refactoring

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored in 3704366. Extracted the common execution logic (applying launch settings, environment variables, telemetry, Ctrl-C handler, and command execution) into a new ExecuteCommand method. Both ExecuteWithProjectProfile and ExecuteWithExecutableProfile now call this method, eliminating the code duplication.

internal void ApplyLaunchSettingsProfileToCommand(ICommand targetCommand, ProjectLaunchSettingsModel? launchSettings)
private int ExecuteWithExecutableProfile(ExecutableLaunchSettingsModel launchSettings)
{
Debug.Assert(launchSettings.ExecutablePath != null);
Copy link
Member

Choose a reason for hiding this comment

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

Might be good idea to add more tests that validate the application of environment expansion and how command line args are constructed.

Copy link
Member

Choose a reason for hiding this comment

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

@copilot please add tests that verify that the executable command handler applies the launch profile settings to the generated command correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added comprehensive tests in 33d9898. The new tests verify:

  1. Environment variables application: Tests that environment variables from the launch profile are correctly applied to the executed command
  2. Working directory settings: Verifies the working directory from the profile is used
  3. Command line arguments combination: Tests that arguments from the profile and command line are properly combined
  4. Environment variable expansion: Validates that executable paths are correctly resolved

Created two new test assets:

  • AppForExecutableProfile: Helper app that prints environment variables and arguments
  • AppWithDetailedExecutableProfile: Test project with multiple executable profiles testing different scenarios

All 6 executable profile tests now pass along with the 11 existing launch settings tests.

Extracted the common code from ExecuteWithProjectProfile and ExecuteWithExecutableProfile into a new ExecuteCommand method. This method handles:
- Applying launch settings to the command
- Applying environment variables from command line
- Sending telemetry
- Setting up Ctrl-C handler
- Executing the command

This reduces code duplication and makes the execution flow clearer.

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
Added tests to verify that the executable command handler correctly applies:
- Environment variables from launch profile
- Working directory settings
- Command line arguments combination (profile + command line)
- Environment variable expansion in executable paths

Created new test assets:
- AppForExecutableProfile: Helper app to verify environment and arguments
- AppWithDetailedExecutableProfile: Test project with various executable profiles

All tests verify the correct application of launch profile settings to the generated command.

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Run Issues relating to `dotnet run` Document for new feature Partner request requests from partners

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants