Skip to content

[spec] better dotnet run extensibility for .NET MAUI#51337

Merged
MiYanni merged 14 commits intodotnet:mainfrom
jonathanpeppers:dev/peppers/dotnet-run-maui
Oct 21, 2025
Merged

[spec] better dotnet run extensibility for .NET MAUI#51337
MiYanni merged 14 commits intodotnet:mainfrom
jonathanpeppers:dev/peppers/dotnet-run-maui

Conversation

@jonathanpeppers
Copy link
Member

The current state of dotnet run for .NET MAUI projects is summarized by this issue from 2021:

This is a WIP spec on how we can solve these problems.

Copy link
Contributor

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 introduces a specification for improving dotnet run extensibility to better support .NET MAUI projects across iOS, Android, and Windows platforms. The spec addresses longstanding issues with device/emulator selection and deployment workflows that have made dotnet run difficult to use for mobile development scenarios.

Key Changes:

  • Defines a new extensibility pipeline for dotnet run with pre-run evaluation, device selection prompts, and a deploy step
  • Introduces --list and --target|-t command-line switches for device/emulator selection
  • Proposes new MSBuild targets (ComputeAvailableTargets and DeployToRunTarget) that workloads can implement

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@baronfel baronfel added Partner request requests from partners Area-Run Issues relating to `dotnet run` labels Oct 17, 2025
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.

Left a couple notes as a quick first pass, but overall this is a great representation of what we discussed the other day.

Would you mind adding a brief section on the applicability/generic-ness of this proposed mechanism and how it might apply to Uno/Avalonia/any other remote-capable tools you may be aware of?

jonathanpeppers and others added 5 commits October 17, 2025 12:18
Co-authored-by: Chet Husk <baronfel@users.noreply.github.com>
Co-authored-by: Chet Husk <baronfel@users.noreply.github.com>
Co-authored-by: Chet Husk <baronfel@users.noreply.github.com>
Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
Copy link
Member

@dsplaisted dsplaisted left a comment

Choose a reason for hiding this comment

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

Looks really good. "Target" already has a meaning for MSBuild, so we may want to disambiguate in some cases. --target would mean something different for dotnet run than it does for other commands like dotnet build. Maybe that's OK. It might be a good idea to rename ComputeAvailableTargets to ComputeAvailableRunTargets.

@baronfel
Copy link
Member

Maybe we use 'device' instead of 'target' like @jonathanpeppers wanted in the first place in our chat? so it'd be dotnet run --list-devices and --device, lifting the 'destination device' concept to a first-class run concept?

@jonathanpeppers
Copy link
Member Author

I updated the doc to use the word "device" in place of "target", so this means:

  • dotnet run --list-devices
  • dotnet run --device Pixel7

We shouldn't use the -d shortcut, as the top-level dotnet command uses it for:

> dotnet --help
Usage: dotnet [runtime-options] [path-to-application] [arguments]

Execute a .NET application.
...
Usage: dotnet [sdk-options] [command] [command-options] [arguments]

Execute a .NET SDK command.

sdk-options:
  -d|--diagnostics  Enable diagnostic output.

* Each platform has different behavior, regards to displaying console
output, etc.

* Using an MSIX with WindowsAppSDK doesn't support `dotnet run` at all,
Copy link
Member

Choose a reason for hiding this comment

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

This is currently a big pain point. There doesn't seem to be an easy way to run packaged WinUI/UWP apps from command-line today?

Copy link
Member

Choose a reason for hiding this comment

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

Also worth noting that we could make much use of that on dotnet test side as well.
WinAppSDK might be the first thing we could support in dotnet test, but Android, iOS, Wasm could follow as well!

Copy link
Member Author

Choose a reason for hiding this comment

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

Since, the dotnet new maui project template is unpackaged right now, I think a future step is to see if we can improve WindowsAppSDK.

Do you know if there are any issues filed about this here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines +33 to +35
* `restore`: unchanged

* "Pre-run evaluation"
Copy link
Member

Choose a reason for hiding this comment

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

There is also a "build" step right?

`--device` switch. Listing the options returned by the
`ComputeAvailableDevices` MSBuild target.

* `build`: unchanged, but is passed `-p:Device`.
Copy link
Member

Choose a reason for hiding this comment

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

Oh I see the build step is mentioned here already. But doesn't it happen before the "pre-run evaluation"?

Copy link
Member

Choose a reason for hiding this comment

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

today, yes - we're proposing changing that, either moving it entirely to the beginning or having a separate evaluation, based on the run-time requirements of the project being run.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, it's unclear to me what would change during the "build" step when it's passed a Device property. How can that change the result of the build?

Copy link
Member

Choose a reason for hiding this comment

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

An iOS project is built differently depending on whether you're building for simulator or device.

This means that you can either first select to run for the simulator or device, and then we'll present all the simulators or all the devices for you to choose from, or we can first present all the simulators + all the devices, and then we automatically build correctly depending on whether you chose a simulator or a device.

Copy link
Member Author

Choose a reason for hiding this comment

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

On Android, debug builds pick a single $(RuntimeIdentifier) for the selected device.

@jonathanpeppers
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines could not run because the pipeline triggers exclude this branch/path.

@MiYanni
Copy link
Member

MiYanni commented Oct 21, 2025

Discussed offline. Helix and BA checks are stuck due to no AzDO pipelines running (skipped). Merging the PR...

@MiYanni MiYanni merged commit ffaba75 into dotnet:main Oct 21, 2025
5 of 7 checks passed
jonathanpeppers added a commit to dotnet/android that referenced this pull request Dec 2, 2025
Context: dotnet/sdk#51337
Context: dotnet/sdk#51914

In 63f7cba, we added the `ComputeAvailableDevices` MSBuild target,
which I was able to test end-to-end:

    D:\src\helloandroid> D:\src\dotnet\sdk\artifacts\bin\redist\Debug\dotnet\dotnet.exe run -bl
    Select a device to run on:

    > 0A041FDD400327 - Pixel 5
    emulator-5554 - pixel 7 - api 36

    Type to search

Unfortunately, the AVD name is returned from `adb emu avd name`, which
simply returns the property:

    > adb -s emulator-5554 shell getprop | grep avd_name
    [ro.boot.qemu.avd_name]: [pixel_7_-_api_36]

We can call `TextInfo.ToTitleCase()`, replace underscores with spaces,
and replace "Api" with "API" to make the AVD name more user-friendly.

The only other alternative I considered was parsing the
`~/.android/avd/<name>.ini` file to get the `displayname` property,
but it would still require calling `adb emu avd name` to *get* the
path to this `.ini` file. It felt more straightforward to just format
the AVD name directly.
jonathanpeppers added a commit to dotnet/android that referenced this pull request Dec 3, 2025
Context: dotnet/sdk#51337
Context: dotnet/sdk#51914

In 63f7cba, we added the `ComputeAvailableDevices` MSBuild target,
which I was able to test end-to-end:

    D:\src\helloandroid> D:\src\dotnet\sdk\artifacts\bin\redist\Debug\dotnet\dotnet.exe run -bl
    Select a device to run on:

    > 0A041FDD400327 - Pixel 5
    emulator-5554 - pixel 7 - api 36

    Type to search

Unfortunately, the AVD name is returned from `adb emu avd name`, which
simply returns the property:

    > adb -s emulator-5554 shell getprop | grep avd_name
    [ro.boot.qemu.avd_name]: [pixel_7_-_api_36]

We can call `TextInfo.ToTitleCase()`, replace underscores with spaces,
and replace "Api" with "API" to make the AVD name more user-friendly.

The only other alternative I considered was parsing the
`~/.android/avd/<name>.ini` file to get the `displayname` property,
but it would still require calling `adb emu avd name` to *get* the
path to this `.ini` file. It felt more straightforward to just format
the AVD name directly.
jonathanpeppers added a commit to dotnet/android that referenced this pull request Jan 21, 2026
Context: dotnet/sdk#51337
Context: dotnet/sdk#51914

In 63f7cba, we added the `ComputeAvailableDevices` MSBuild target,
which I was able to test end-to-end:

    D:\src\helloandroid> D:\src\dotnet\sdk\artifacts\bin\redist\Debug\dotnet\dotnet.exe run -bl
    Select a device to run on:

    > 0A041FDD400327 - Pixel 5
    emulator-5554 - pixel 7 - api 36

    Type to search

Unfortunately, the AVD name is returned from `adb emu avd name`, which
simply returns the property:

    > adb -s emulator-5554 shell getprop | grep avd_name
    [ro.boot.qemu.avd_name]: [pixel_7_-_api_36]

We can call `TextInfo.ToTitleCase()`, replace underscores with spaces,
and replace "Api" with "API" to make the AVD name more user-friendly.

The only other alternative I considered was parsing the
`~/.android/avd/<name>.ini` file to get the `displayname` property,
but it would still require calling `adb emu avd name` to *get* the
path to this `.ini` file. It felt more straightforward to just format
the AVD name directly.
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` Partner request requests from partners

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants