You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
When running a project, dotnet run has a protocol that it implements to determine how to run the project:
Detect the project that should be run
Determine the 'launch settings' and profile that will be applied to the project
Build the project if required
Determine the RunCommand/RunArguments/RunWorkingDirectory for the project to create an executable ICommand
Apply 'launch settings' to the ICommand
Invoke the ICommand
In a graphic this looks like:
sequenceDiagram
participant dotnet as dotnet CLI
participant project as myproj.proj
participant exe as RunCommand
dotnet->>dotnet: detect project to run
dotnet->>dotnet: read launch settings from file and pick launch profile
dotnet->>project: build project (if required)
dotnet->>project: evaluate project to get run settings
dotnet->>exe: create process to spawn from run settings
dotnet->>exe: apply launch profile to process
dotnet->>exe: spawn process
dotnet->>exe: run process to completion
Loading
This process relies on MSBuild evaluation to determine the RunCommand/RunArguments/RunWorkingDirectory, which means that these values can only be set during evaluation - no code or logic can run to influence their values. This can be highly limiting and means that use cases that need to run some dynamic logic to determine a value to put in the RunWorkingDirectory, for example, cannot be safely run.
Describe the solution you'd like
We should have an opt-in protocol that would allow dotnet run to invoke a target to get the RunCommand/RunArguments/RunWorkingDirectory data. This target should be public and documented and would update step 4 above as follows:
Determine the RunCommand/RunArguments/RunWorkingDirectory for the project to create an executable ICommand
a. if the project supports a ComputeRunCommand Target, then run that target and read the RunCommand/RunArguments/RunWorkingDirectory after target execution
b. otherwise read the same properties just after evaluation, as is done today
c. when called, this target would be passed all of the same MSBuild properties as applied to the implicit build in step 3
In a graphic this would look like:
sequenceDiagram
participant dotnet as dotnet CLI
participant project as myproj.proj
participant exe as RunCommand
dotnet->>dotnet: detect project to run
dotnet->>dotnet: read launch settings from file and pick launch profile
dotnet->>project: build project (if required)
dotnet->>project: evaluate project
dotnet->>project: invoke target to get run settings
project->>dotnet: return run settings
dotnet->>exe: create process to spawn from run settings
dotnet->>exe: apply launch profile to process
dotnet->>exe: spawn process
dotnet->>exe: run process to completion
Loading
Run Command Protocol
This new target would need to define its protocol
Name
Dependencies - what is a reasonable dependency chain for this Target? How do projects like MAUI change this dependency chain?
Outputs - should the target set properties, or should we take the opportunity to make a different representation
Opting-in
Projects would need to opt into the new behavior - the SDK currently computes the values here and so could change this for SDK-style projects as a default. Should there be a property-based opt-in, or should we just start doing this wholesale since the CLI and SDK targets change in lockstep?
Use cases like Azure Functions or MAUI may want to override the generation and so could override the target or set up a BeforeTargets, etc.
Compatibility
The MSBuild Run target defined in the SDK should have a dependency on the new target if defined.
The dotnet watch command currently uses the RunCommand/RunArguments/RunWorkingDirectory as inputs to GenerateWatchList - it will need to become aware of this target if necessary as well.
We should add a new ProjectCapability signalling that a Project uses this new mechanism, so that IDEs have a flag for behavior.
The new Target could be integrated into the Design-Time Build dependency chain.
Binlogs
We would to to ensure that if a binlog was requested that the configured binlog logger also applied to this new target, not just the implicit build + project evaluation for Run argument discovery
Is your feature request related to a problem? Please describe.
When running a project,
dotnet runhas a protocol that it implements to determine how to run the project:In a graphic this looks like:
This process relies on MSBuild evaluation to determine the RunCommand/RunArguments/RunWorkingDirectory, which means that these values can only be set during evaluation - no code or logic can run to influence their values. This can be highly limiting and means that use cases that need to run some dynamic logic to determine a value to put in the RunWorkingDirectory, for example, cannot be safely run.
Describe the solution you'd like
We should have an opt-in protocol that would allow
dotnet runto invoke a target to get the RunCommand/RunArguments/RunWorkingDirectory data. This target should be public and documented and would update step 4 above as follows:a. if the project supports a ComputeRunCommand Target, then run that target and read the RunCommand/RunArguments/RunWorkingDirectory after target execution
b. otherwise read the same properties just after evaluation, as is done today
c. when called, this target would be passed all of the same MSBuild properties as applied to the implicit build in step 3
In a graphic this would look like:
Run Command Protocol
This new target would need to define its protocol
Opting-in
Projects would need to opt into the new behavior - the SDK currently computes the values here and so could change this for SDK-style projects as a default. Should there be a property-based opt-in, or should we just start doing this wholesale since the CLI and SDK targets change in lockstep?
Use cases like Azure Functions or MAUI may want to override the generation and so could override the target or set up a BeforeTargets, etc.
Compatibility
dotnet watchcommand currently uses the RunCommand/RunArguments/RunWorkingDirectory as inputs toGenerateWatchList- it will need to become aware of this target if necessary as well.Binlogs
We would to to ensure that if a binlog was requested that the configured binlog logger also applied to this new target, not just the implicit build + project evaluation for Run argument discovery
Additional context
@captainsafia for Aspire
@fabiocav for Functions
@jonathanpeppers for MAUI
@danroth27 for web
@tmat for watch
@tmeschter for project-system