Fix emulator boot and deploy flow for dotnet run#10969
Open
Fix emulator boot and deploy flow for dotnet run#10969
dotnet run#10969Conversation
This was referenced Mar 18, 2026
Merged
Member
jonathanpeppers
left a comment
There was a problem hiding this comment.
The problem on the description sounds like:
Which should be in main, if you have at least:
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes dotnet run --project <app>.csproj deploy failures when the selected Android emulator is stopped by ensuring the emulator-boot target runs via DependsOnTargets, and improving emulator detection/boot polling in the BootAndroidEmulator MSBuild task.
Changes:
- Add
_EnsureDeviceBootedintoDeployToDeviceDependsOnTargetsand_AndroidComputeRunArgumentsDependsOnso it runs reliably during in-procProjectInstance.Build(["DeployToDevice"]). - Improve AVD name detection by preferring
adb shell getprop ro.boot.qemu.avd_name, with fallback toadb emu avd name. - Handle macOS emulator launcher “fork then exit 0” behavior by continuing to poll
adb deviceson exit code 0. - Add a unit test asserting
_EnsureDeviceBootedis included inDeployToDeviceDependsOnTargets.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Application.targets | Ensures _EnsureDeviceBooted participates in run-argument computation and clarifies execution rationale. |
| src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets | Adds _EnsureDeviceBooted to deploy dependency chains (fast deploy + non-fast deploy). |
| src/Xamarin.Android.Build.Tasks/Tasks/BootAndroidEmulator.cs | Updates AVD name detection and improves macOS emulator process exit handling. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildOrderTests.cs | Adds coverage to validate deploy dependency chain includes _EnsureDeviceBooted. |
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
282
to
+285
| if (outputLines.Count > 0) { | ||
| var name = outputLines [0].Trim (); | ||
| if (!name.IsNullOrEmpty () && !name.Equals ("OK", StringComparison.OrdinalIgnoreCase)) { | ||
| avdName = name; | ||
| var consoleName = outputLines [0].Trim (); | ||
| if (!consoleName.IsNullOrEmpty () && !consoleName.Equals ("OK", StringComparison.OrdinalIgnoreCase)) { | ||
| avdName = consoleName; |
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildOrderTests.cs
Outdated
Show resolved
Hide resolved
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildOrderTests.cs
Show resolved
Hide resolved
aa3f844 to
d188a4b
Compare
cf51ffd to
62a458e
Compare
Address multiple issues preventing 'dotnet run --project' from successfully booting an Android emulator and deploying the app. Fixes: #10965 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add init.svc.bootanim check to WaitForFullBoot so we wait for the boot animation to stop before considering the emulator ready - Detect 'used by another emulator' from stderr and fail fast with a clear error instead of silently timing out after 300 seconds - Upgrade key milestone log messages to MessageImportance.High so users see progress during emulator boot (appeared online, system boot complete, fully ready) with elapsed times Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The dotnet/sdk fix (dotnet/sdk#53018) now properly passes the Device global property to DeployToDevice via InvalidateGlobalProperties. Remove the device.props write/read cache that was working around this. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove non-essential improvements (AVD lock detection, offline detection, boot animation check, log message changes) to keep the diff minimal. Only the three actual bug fixes remain: getprop AVD detection, fork handling, and error reporting for non-zero exit codes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The emulator is already booted by ComputeAvailableDevices before _EnsureDeviceBooted runs, so the task never launches a new emulator process and the fork issue doesn't apply. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The DeployToDeviceDependsOnTargets property expands to multiple log lines because it includes $(_MinimalSignAndroidPackageDependsOn). The test was only checking the first line, which never contained _EnsureDeviceBooted. Switch to MSBuild property functions (Contains/IndexOf) to validate directly in MSBuild, avoiding log parsing entirely. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
62a458e to
a2787ca
Compare
Keep the readable log-parsing approach (fixed by joining all output lines for multi-line property matching) and add a separate MSBuild property function test as a safety net. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Running
dotnet run --project <app>.csprojwith a stopped Android emulator fails to boot the emulator and deploy the app, producingadb: no devices/emulators foundoradb: device '<avd>' not founderrors.This PR fixes two issues in the emulator boot and deploy flow.
Fixes #10965
Problems & Fixes
1.
_EnsureDeviceBootednot firing duringDeployToDeviceThe .NET SDK's
dotnet runinvokesDeployToDeviceviaProjectInstance.Build(["DeployToDevice"])in-process. In this execution mode,BeforeTargetshooks are not reliably triggered — onlyDependsOnTargetschains are respected.Fix: Add
_EnsureDeviceBootedtoDeployToDeviceDependsOnTargetsinBuildOrder.targets, and to_AndroidComputeRunArgumentsDependsOninApplication.targets, ensuring the emulator boots via the dependency chain during both the main build and the deploy step.2.
adb emu avd namereturns empty on modern emulatorsGetRunningAvdNameusedadb -s <serial> emu avd nameto match running emulators to AVD names. On modern Android emulators (tested with emulator 36.4.10), this command returns zero bytes, causing the match to fail even when the correct emulator is already running.Fix: Try
adb shell getprop ro.boot.qemu.avd_namefirst (always set on emulators), falling back toemu avd namefor older emulator versions.Changes
Microsoft.Android.Sdk.Application.targets— Added_EnsureDeviceBootedto_AndroidComputeRunArgumentsDependsOn, simplifiedBeforeTargetsto just_GetPrimaryCpuAbi(commercial builds), updated commentsMicrosoft.Android.Sdk.BuildOrder.targets— Added_EnsureDeviceBootedto bothDeployToDeviceDependsOnTargetsvariantsBootAndroidEmulator.cs— Fixed AVD name detection (getprop ro.boot.qemu.avd_namefirst, fallback toemu avd name)BuildOrderTests.cs— AddedDeployToDeviceDependsOn_ContainsEnsureDeviceBootedtestTesting
DeployToDeviceDependsOn_ContainsEnsureDeviceBootedvalidates the target chainMAUI_Emulator_API_36(API 36), .NET 11 preview — emulator boots from cold, app deploys and launches with logcat streaming