diff --git a/documentation/specs/dotnet-run-for-maui.md b/documentation/specs/dotnet-run-for-maui.md
new file mode 100644
index 000000000000..33fd374d8b67
--- /dev/null
+++ b/documentation/specs/dotnet-run-for-maui.md
@@ -0,0 +1,243 @@
+# `dotnet run` for .NET MAUI Scenarios
+
+The current state of `dotnet run` for .NET MAUI projects is summarized
+by this issue from 2021:
+
+* [Figure out 'dotnet run' CLI experience for iOS and Android](https://github.com/dotnet/xamarin/issues/26)
+
+The pain points being:
+
+* iOS and Android use different properties to select a device,
+ emulator, or simulator. It is difficult for developers to make this
+ selection as you need to run platform-specific commands along with
+ complex MSBuild properties.
+
+* Each platform has different behavior, regards to displaying console
+ output, etc.
+
+* Using an MSIX with WindowsAppSDK doesn't support `dotnet run` at all,
+ relying completely on IDEs like Visual Studio.
+
+* `dotnet run` does not have a concept of a "deploy" step.
+
+This has become more relevant in the AI era, as someone is going to
+expect AIs in "agent mode" to build and run their app. If the
+command-line options are difficult, AIs will fail just as badly as
+humans do today.
+
+## The `dotnet run` Pipeline
+
+These are the high-level steps during `dotnet run`, that we would like
+to make extensible for .NET MAUI (and future) scenarios.
+
+* `restore`: unchanged
+
+* "Pre-run evaluation"
+
+ * If the project is multi-targeted, containing the
+ `$(TargetFrameworks)` property _and_ that property has more than
+ one item in it, and `-f` was not supplied...
+
+ * Prompt the user to select from a list of the
+ `$(TargetFrameworks)`
+
+ * Non-interactive mode will give a friendly error message,
+ suggesting to supply the `-f` property, listing available target
+ frameworks in the project.
+
+ * Once a `$(TargetFramework)` is selected, either from previous
+ steps or `-f`...
+
+ * If a `ComputeAvailableDevices` MSBuild target is available, provided by
+ the iOS or Android workload, etc. ...
+
+ * Call the MSBuild target, which returns a list of `@(Devices)` items...
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+```
+
+_NOTE: each workload can decide which metadata values for `%(Type)`,
+`%(Status)`, and `%(RuntimeIdentifier)` are useful, filtering offline
+devices, etc. The output above would be analogous to running `adb
+devices`, `xcrun simctl list devices`, or `xcrun devicectl list
+devices`. The `%(RuntimeIdentifier)` metadata is optional but
+recommended, as it allows the build system to pass the appropriate RID
+to subsequent build, deploy, and run steps._
+
+* Continuing on...
+
+ * Prompt the user to select from this list of devices, emulators,
+ or simulators.
+
+ * Non-interactive mode will error, suggesting to supply the
+ `--device` switch. Listing the options returned by the
+ `ComputeAvailableDevices` MSBuild target.
+
+* `build`: unchanged, but is passed `-p:Device` and optionally `-p:RuntimeIdentifier`
+ if the selected device provided a `%(RuntimeIdentifier)` metadata value.
+
+* `deploy`
+
+ * If a `DeployToDevice` MSBuild target is available, provided by the
+ iOS or Android workload, etc.
+
+ * Call the MSBuild target, passing in the identifier for the selected
+ `-p:Device` global MSBuild property, and optionally `-p:RuntimeIdentifier`
+ if the selected device provided a `%(RuntimeIdentifier)` metadata value.
+
+ * This step needs to run, even with `--no-build`, as you may have
+ selected a different device.
+
+* `ComputeRunArguments`: unchanged, but is passed `-p:Device` and optionally
+ `-p:RuntimeIdentifier` if the selected device provided a `%(RuntimeIdentifier)`
+ metadata value.
+
+* `run`: unchanged. `ComputeRunArguments` should have set a valid
+ `$(RunCommand)` and `$(RunArguments)` using the value supplied by
+ `-p:Device` and optionally `-p:RuntimeIdentifier`.
+
+## New `dotnet run` Command-line Switches
+
+So far, it feels like no new subcommand is needed. In interactive
+mode, `dotnet run` will now prompt to select a `$(TargetFramework)`
+for all multi-targeted projects. Platform-specific projects like
+Android, iOS, etc. will prompt for device selection.
+
+`dotnet run --list-devices` will:
+
+* Prompt for `$(TargetFramework)` for multi-targeted projects just
+ like when `--list-devices` is omitted.
+
+ * If there is a single `$(TargetFramework)`, skip to the next step.
+
+* Call `ComputeAvailableDevices` if the MSBuild target exists, just
+ like when `--list-devices` is omitted.
+
+ * List the available targets by name, a unique identifier, and an
+ optional status of the device.
+
+ * Print a friendly message that says how to run `dotnet run` with
+ the new `--device` switch.
+
+ * If `ComputeAvailableDevices` does not exist in the project
+ (workload), it can print a friendly message and exit.
+
+* `dotnet run --list-devices` will then basically exit early, never
+ running any build, deploy, `ComputeRunArguments`, or run steps.
+
+A new `--device` switch will:
+
+* bypass the device-selection portion of the `run` workflow described above
+
+* Pass in the `-p:Device` global MSBuild property to all build,
+ deploy, `ComputeRunArguments`, or run steps.
+
+* The iOS and Android workloads will know how to interpret `$(Device)`
+ to select an appropriate device, emulator, or simulator.
+
+## Binary Logs for Device Selection
+
+When using `-bl` with `dotnet run`, all MSBuild operations are logged to a single
+binlog file: device selection, build, deploy, and run argument computation.
+
+File naming for `dotnet run` binlogs:
+
+* `-bl:filename.binlog` creates `filename-dotnet-run.binlog`
+* `-bl` creates `msbuild-dotnet-run.binlog`
+
+Note: The build step may also create `msbuild.binlog` separately. Use
+`--no-build` with `-bl` to only capture run-specific MSBuild
+operations.
+
+## What about Launch Profiles?
+
+The iOS and Android workloads ignore all
+`Properties/launchSettings.json` files and do nothing with them.
+
+WindowsAppSDK requires a launch profile to select between "packaged"
+MSIX and an "unpackaged" .exe, and so we currently provide this in the
+`dotnet new maui` project template:
+
+```json
+{
+ "profiles": {
+ "Windows Machine": {
+ "commandName": "Project",
+ "nativeDebugging": false
+ }
+ }
+}
+```
+
+Or if you want to be "packaged":
+
+```json
+{
+ "profiles": {
+ "Windows Machine": {
+ "commandName": "MsixPackage",
+ "nativeDebugging": false
+ }
+ }
+}
+```
+
+Launch profiles don't immediately look useful for iOS or Android, as
+the identifier you'd put in here would be different per developer --
+you wouldn't want the value saved in source control. You could put a
+generic selection like device vs emulator/simulator, but that isn't
+addressing the problem we are interested in. Full launch profile
+support for .NET MAUI projects may be interesting to address in the
+future.
+
+## iOS and Android workload behavior
+
+We will work to align as much behavior as possible between the
+platforms. Most of this work will happen in the dotnet/android and
+dotnet/macios repo, and would be orthogonal to the changes in the .NET
+SDK.
+
+## macOS and MacCatalyst Behavior
+
+`dotnet run` "just works" on macOS Desktop, because `$(RunCommand)`
+can launch the app directly -- similar to console apps.
+
+## WindowsAppSDK Behavior
+
+Running a `dotnet new maui` project works today because of the default
+launch profile in "unpackaged" mode:
+
+```dotnetcli
+> dotnet run -f net10.0-windows10.0.19041.0
+Using launch settings from D:\src\hellomaui\Properties\launchSettings.json...
+```
+
+To improve the behavior for "packaged" / MSIX, we could:
+
+* Implement the `DeployToDevice` MSBuild target.
+
+* `ComputeAvailableDevices` is not needed.
+
+* Implement the `ComputeRunArguments` MSBuild target.
+
+In the future, we can either add this logic into the .NET MAUI
+workload or WindowsAppSDK itself.
+
+## Other frameworks: Avalonia, Uno, MonoGame, etc.
+
+When these frameworks run on iOS or Android, they are basically using
+the `ios` and `android` workloads _without_ .NET MAUI. Any iOS or
+Android-specific behavior would apply to these project types in the
+same way a `dotnet new android` or `dotnet new ios` project template
+would.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/CommandDefinitionStrings.resx b/src/Cli/Microsoft.DotNet.Cli.Definitions/CommandDefinitionStrings.resx
index a6a7be1c8fd7..2b173efd5745 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/CommandDefinitionStrings.resx
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/CommandDefinitionStrings.resx
@@ -675,6 +675,15 @@ If not specified the file will be generated inside the default 'TestResults' dir
Do not attempt to use launchSettings.json or [app].run.json to configure the application.{Locked="launchSettings.json"}{Locked=".run.json"}
+
+ The device identifier to use for running the application.
+
+
+ DEVICE
+
+
+ List available devices for running the application.
+
PROJECT_PATH
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/Commands/Run/RunCommandDefinition.cs b/src/Cli/Microsoft.DotNet.Cli.Definitions/Commands/Run/RunCommandDefinition.cs
index f689ca30ec27..fd646939939b 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/Commands/Run/RunCommandDefinition.cs
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/Commands/Run/RunCommandDefinition.cs
@@ -48,6 +48,18 @@ internal sealed class RunCommandDefinition : Command
Description = CommandDefinitionStrings.CommandOptionNoLaunchProfileArgumentsDescription
};
+ public readonly Option DeviceOption = new("--device")
+ {
+ Description = CommandDefinitionStrings.CommandOptionDeviceDescription,
+ HelpName = CommandDefinitionStrings.CommandOptionDeviceHelpName
+ };
+
+ public readonly Option ListDevicesOption = new("--list-devices")
+ {
+ Description = CommandDefinitionStrings.CommandOptionListDevicesDescription,
+ Arity = ArgumentArity.Zero
+ };
+
public const string NoBuildOptionName = "--no-build";
public readonly Option NoBuildOption = new(NoBuildOptionName)
@@ -98,6 +110,8 @@ public RunCommandDefinition()
Options.Add(PropertyOption);
Options.Add(LaunchProfileOption);
Options.Add(NoLaunchProfileOption);
+ Options.Add(DeviceOption);
+ Options.Add(ListDevicesOption);
Options.Add(NoBuildOption);
Options.Add(InteractiveOption);
Options.Add(NoRestoreOption);
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.cs.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.cs.xlf
index 344d247cba33..1700afa47926 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.cs.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.cs.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.de.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.de.xlf
index 1b0f210ff433..e53f6bae92ae 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.de.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.de.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.es.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.es.xlf
index c17a0593d409..0d53ea87e5c1 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.es.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.es.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.fr.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.fr.xlf
index a6b3b0f3f4bd..51c4cb9cf62f 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.fr.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.fr.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.it.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.it.xlf
index 52179b3e1116..0891c63cbcf7 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.it.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.it.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ja.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ja.xlf
index 803bdb7d5b23..b954efbc4d98 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ja.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ja.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ko.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ko.xlf
index 75be8a8982e1..d6e1e93b1191 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ko.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ko.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.pl.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.pl.xlf
index 0d9801e04f09..06fd257a5bc6 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.pl.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.pl.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.pt-BR.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.pt-BR.xlf
index 561a1cf08daf..77c2f424c490 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.pt-BR.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.pt-BR.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ru.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ru.xlf
index d6ff51db95aa..d4ce1f5ed8f8 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ru.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.ru.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.tr.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.tr.xlf
index e16aabe87fd9..b6583aa3fada 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.tr.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.tr.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.zh-Hans.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.zh-Hans.xlf
index 82c030054ef7..429f270fa145 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.zh-Hans.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.zh-Hans.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.zh-Hant.xlf b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.zh-Hant.xlf
index 7b6c4848b2d1..77ccfc8c62c3 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.zh-Hant.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/xlf/CommandDefinitionStrings.zh-Hant.xlf
@@ -743,6 +743,16 @@ Examples:
COMMAND_NAME
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+ The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).The path to the file-based app to run (can be also passed as the first argument if there is no project in the current directory).
@@ -763,6 +773,11 @@ Examples:
LAUNCH_PROFILE
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Do not build the project before running. Implies --no-restore.Do not build the project before running. Implies --no-restore.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs
index 0c5aef161367..598d1dfe3483 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs
@@ -29,6 +29,8 @@ public static class Constants
// MSBuild targets
public const string Build = nameof(Build);
public const string ComputeRunArguments = nameof(ComputeRunArguments);
+ public const string ComputeAvailableDevices = nameof(ComputeAvailableDevices);
+ public const string DeployToDevice = nameof(DeployToDevice);
public const string CoreCompile = nameof(CoreCompile);
// MSBuild item metadata
diff --git a/src/Cli/dotnet/Commands/CliCommandStrings.resx b/src/Cli/dotnet/Commands/CliCommandStrings.resx
index cd5cae271f0d..c1d47a523067 100644
--- a/src/Cli/dotnet/Commands/CliCommandStrings.resx
+++ b/src/Cli/dotnet/Commands/CliCommandStrings.resx
@@ -923,6 +923,9 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
The build failed. Fix the build errors and run again.
+
+ Deployment to device failed. Fix any deployment errors and run again.
+
The launch profile "{0}" could not be applied.
{1}
@@ -986,6 +989,30 @@ Your project targets multiple frameworks. Specify which framework to run using '
The target runtime to run for.
+
+ The device identifier to use for running the application.
+
+
+ DEVICE
+
+
+ List available devices for running the application.
+
+
+ Available devices:
+
+
+ No devices are available for this project.
+
+
+ Select a device to run on:
+
+
+ Move up and down to reveal more devices
+
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
Path to <application>.runtimeconfig.json file.
diff --git a/src/Cli/dotnet/Commands/Run/Api/RunApiCommand.cs b/src/Cli/dotnet/Commands/Run/Api/RunApiCommand.cs
index 8217e1744580..40e5a2cd07fc 100644
--- a/src/Cli/dotnet/Commands/Run/Api/RunApiCommand.cs
+++ b/src/Cli/dotnet/Commands/Run/Api/RunApiCommand.cs
@@ -106,6 +106,8 @@ public override RunApiOutput Execute()
launchProfile: null,
noLaunchProfile: false,
noLaunchProfileArguments: false,
+ device: null,
+ listDevices: false,
noRestore: false,
noCache: false,
interactive: false,
@@ -115,7 +117,7 @@ public override RunApiOutput Execute()
environmentVariables: ReadOnlyDictionary.Empty);
var result = runCommand.ReadLaunchProfileSettings();
- var targetCommand = (Utils.Command)runCommand.GetTargetCommand(result.Profile, buildCommand.CreateProjectInstance, cachedRunProperties: null);
+ var targetCommand = (Utils.Command)runCommand.GetTargetCommand(result.Profile, buildCommand.CreateProjectInstance, cachedRunProperties: null, logger: null);
return new RunApiOutput.RunCommand
{
diff --git a/src/Cli/dotnet/Commands/Run/RunCommand.cs b/src/Cli/dotnet/Commands/Run/RunCommand.cs
index 40a21c7f1f7e..66e3e05af9ae 100644
--- a/src/Cli/dotnet/Commands/Run/RunCommand.cs
+++ b/src/Cli/dotnet/Commands/Run/RunCommand.cs
@@ -86,6 +86,22 @@ public class RunCommand
///
public bool NoLaunchProfileArguments { get; }
+ ///
+ /// Device identifier to use for running the application.
+ ///
+ public string? Device { get; }
+
+ ///
+ /// Whether to list available devices and exit.
+ ///
+ public bool ListDevices { get; }
+
+ ///
+ /// Tracks whether restore was performed during device selection phase.
+ /// If true, we should skip restore in the build phase to avoid redundant work.
+ ///
+ private bool _restoreDoneForDeviceSelection;
+
/// unparsed/arbitrary CLI tokens to be passed to the running application
public RunCommand(
bool noBuild,
@@ -94,6 +110,8 @@ public RunCommand(
string? launchProfile,
bool noLaunchProfile,
bool noLaunchProfileArguments,
+ string? device,
+ bool listDevices,
bool noRestore,
bool noCache,
bool interactive,
@@ -112,6 +130,8 @@ public RunCommand(
LaunchProfile = launchProfile;
NoLaunchProfile = noLaunchProfile;
NoLaunchProfileArguments = noLaunchProfileArguments;
+ Device = device;
+ ListDevices = listDevices;
ApplicationArgs = applicationArgs;
Interactive = interactive;
NoRestore = noRestore;
@@ -127,90 +147,186 @@ public int Execute()
throw new GracefulException(CliCommandStrings.CannotCombineOptions, RunCommandDefinition.NoCacheOptionName, RunCommandDefinition.NoBuildOptionName);
}
- // Pre-run evaluation: Handle target framework selection for multi-targeted projects
- if (ProjectFileFullPath is not null && !TrySelectTargetFrameworkIfNeeded())
+ // Create a single logger for all MSBuild operations (device selection + build/run)
+ // File-based runs (.cs files) don't support device selection and should use the existing logger behavior
+ FacadeLogger? logger = ProjectFileFullPath is not null
+ ? LoggerUtility.DetermineBinlogger([.. MSBuildArgs.OtherMSBuildArgs], "dotnet-run")
+ : null;
+ try
{
- return 1;
- }
+ // Pre-run evaluation: Handle target framework and device selection for project-based scenarios
+ using var selector = ProjectFileFullPath is not null
+ ? new RunCommandSelector(ProjectFileFullPath, Interactive, MSBuildArgs, logger)
+ : null;
+ if (selector is not null && !TrySelectTargetFrameworkAndDeviceIfNeeded(selector))
+ {
+ // If --list-devices was specified, this is a successful exit
+ return ListDevices ? 0 : 1;
+ }
- // For file-based projects, check for multi-targeting before building
- if (EntryPointFileFullPath is not null && !TrySelectTargetFrameworkForFileBasedProject())
- {
- return 1;
- }
+ // For file-based projects, check for multi-targeting before building
+ if (EntryPointFileFullPath is not null && !TrySelectTargetFrameworkForFileBasedProject())
+ {
+ return 1;
+ }
- var launchProfileParseResult = ReadLaunchProfileSettings();
- if (launchProfileParseResult.FailureReason != null)
- {
- Reporter.Error.WriteLine(string.Format(CliCommandStrings.RunCommandExceptionCouldNotApplyLaunchSettings, LaunchProfileParser.GetLaunchProfileDisplayName(LaunchProfile), launchProfileParseResult.FailureReason).Bold().Red());
- }
+ var launchProfileParseResult = ReadLaunchProfileSettings();
+ if (launchProfileParseResult.FailureReason != null)
+ {
+ Reporter.Error.WriteLine(string.Format(CliCommandStrings.RunCommandExceptionCouldNotApplyLaunchSettings, LaunchProfileParser.GetLaunchProfileDisplayName(LaunchProfile), launchProfileParseResult.FailureReason).Bold().Red());
+ }
- Func? projectFactory = null;
- RunProperties? cachedRunProperties = null;
- VirtualProjectBuildingCommand? projectBuilder = null;
- if (ShouldBuild)
- {
- if (launchProfileParseResult.Profile?.DotNetRunMessages == true)
+ Func? projectFactory = null;
+ RunProperties? cachedRunProperties = null;
+ VirtualProjectBuildingCommand? projectBuilder = null;
+ if (ShouldBuild)
{
- Reporter.Output.WriteLine(CliCommandStrings.RunCommandBuilding);
+ if (launchProfileParseResult.Profile?.DotNetRunMessages == true)
+ {
+ Reporter.Output.WriteLine(CliCommandStrings.RunCommandBuilding);
+ }
+
+ EnsureProjectIsBuilt(out projectFactory, out cachedRunProperties, out projectBuilder);
}
+ else if (EntryPointFileFullPath is not null && launchProfileParseResult.Profile is not ExecutableLaunchProfile)
+ {
+ // The entry-point is not used to run the application if the launch profile specifies Executable command.
- EnsureProjectIsBuilt(out projectFactory, out cachedRunProperties, out projectBuilder);
- }
- else if (EntryPointFileFullPath is not null && launchProfileParseResult.Profile is not ExecutableLaunchProfile)
- {
- // The entry-point is not used to run the application if the launch profile specifies Executable command.
+ Debug.Assert(!ReadCodeFromStdin);
+ projectBuilder = CreateProjectBuilder();
+ projectBuilder.MarkArtifactsFolderUsed();
- Debug.Assert(!ReadCodeFromStdin);
- projectBuilder = CreateProjectBuilder();
- projectBuilder.MarkArtifactsFolderUsed();
+ var cacheEntry = projectBuilder.GetPreviousCacheEntry();
+ projectFactory = CanUseRunPropertiesForCscBuiltProgram(BuildLevel.None, cacheEntry) ? null : projectBuilder.CreateProjectInstance;
+ cachedRunProperties = cacheEntry?.Run;
+ }
- var cacheEntry = projectBuilder.GetPreviousCacheEntry();
- projectFactory = CanUseRunPropertiesForCscBuiltProgram(BuildLevel.None, cacheEntry) ? null : projectBuilder.CreateProjectInstance;
- cachedRunProperties = cacheEntry?.Run;
- }
+ // Deploy step: Call DeployToDevice target if available
+ // This must run even with --no-build, as the user may have selected a different device
+ if (selector is not null && !selector.TryDeployToDevice())
+ {
+ // Only error if we have a valid project (not a .sln file, etc.)
+ if (selector.HasValidProject)
+ {
+ throw new GracefulException(CliCommandStrings.RunCommandDeployFailed);
+ }
+ }
- var targetCommand = GetTargetCommand(launchProfileParseResult.Profile, projectFactory, cachedRunProperties);
+ var targetCommand = GetTargetCommand(launchProfileParseResult.Profile, projectFactory, cachedRunProperties, logger);
- // Send telemetry about the run operation
- SendRunTelemetry(launchProfileParseResult.Profile, projectBuilder);
+ // Send telemetry about the run operation
+ SendRunTelemetry(launchProfileParseResult.Profile, projectBuilder);
- // Ignore Ctrl-C for the remainder of the command's execution
- Console.CancelKeyPress += (sender, e) => { e.Cancel = true; };
+ // Ignore Ctrl-C for the remainder of the command's execution
+ Console.CancelKeyPress += (sender, e) => { e.Cancel = true; };
- return targetCommand.Execute().ExitCode;
+ return targetCommand.Execute().ExitCode;
+ }
+ catch (InvalidProjectFileException e)
+ {
+ throw new GracefulException(
+ string.Format(CliCommandStrings.RunCommandSpecifiedFileIsNotAValidProject, ProjectFileFullPath),
+ e);
+ }
+ finally
+ {
+ logger?.ReallyShutdown();
+ }
}
- internal ICommand GetTargetCommand(LaunchProfile? launchSettings, Func? projectFactory, RunProperties? cachedRunProperties)
+ internal ICommand GetTargetCommand(LaunchProfile? launchSettings, Func? projectFactory, RunProperties? cachedRunProperties, FacadeLogger? logger)
=> launchSettings switch
{
- null => GetTargetCommandForProject(launchSettings: null, projectFactory, cachedRunProperties),
- ProjectLaunchProfile projectSettings => GetTargetCommandForProject(projectSettings, projectFactory, cachedRunProperties),
+ null => GetTargetCommandForProject(launchSettings: null, projectFactory, cachedRunProperties, logger),
+ ProjectLaunchProfile projectSettings => GetTargetCommandForProject(projectSettings, projectFactory, cachedRunProperties, logger),
ExecutableLaunchProfile executableSettings => GetTargetCommandForExecutable(executableSettings),
_ => throw new InvalidOperationException()
};
///
- /// Checks if target framework selection is needed for multi-targeted projects.
- /// If needed and we're in interactive mode, prompts the user to select a framework.
- /// If needed and we're in non-interactive mode, shows an error.
+ /// Checks if target framework selection and device selection are needed.
+ /// Uses a single RunCommandSelector instance for both operations, re-evaluating
+ /// the project after framework selection to get the correct device list.
///
+ /// The RunCommandSelector instance to use for selection
/// True if we can continue, false if we should exit
- private bool TrySelectTargetFrameworkIfNeeded()
+ private bool TrySelectTargetFrameworkAndDeviceIfNeeded(RunCommandSelector selector)
{
- Debug.Assert(ProjectFileFullPath is not null);
-
var globalProperties = CommonRunHelpers.GetGlobalPropertiesFromArgs(MSBuildArgs);
- if (TargetFrameworkSelector.TrySelectTargetFramework(
- ProjectFileFullPath,
- globalProperties,
- Interactive,
- out string? selectedFramework))
+
+ // If user specified --device on command line, add it to global properties and MSBuildArgs
+ if (!string.IsNullOrWhiteSpace(Device))
+ {
+ globalProperties["Device"] = Device;
+ var properties = new Dictionary { { "Device", Device } };
+ var additionalProperties = new ReadOnlyDictionary(properties);
+ MSBuildArgs = MSBuildArgs.CloneWithAdditionalProperties(additionalProperties);
+ }
+
+ // Optimization: If BOTH framework AND device are already specified (and we're not listing devices),
+ // we can skip both framework selection and device selection entirely
+ bool hasFramework = globalProperties.TryGetValue("TargetFramework", out var existingFramework) && !string.IsNullOrWhiteSpace(existingFramework);
+ bool hasDevice = globalProperties.TryGetValue("Device", out var preSpecifiedDevice) && !string.IsNullOrWhiteSpace(preSpecifiedDevice);
+
+ if (!ListDevices && hasFramework && hasDevice)
+ {
+ // Both framework and device are pre-specified
+ return true;
+ }
+
+ // Step 1: Select target framework if needed
+ if (!selector.TrySelectTargetFramework(out string? selectedFramework))
+ {
+ return false;
+ }
+
+ if (selectedFramework is not null)
{
ApplySelectedFramework(selectedFramework);
+
+ // Re-evaluate project with the selected framework so device selection sees the right devices
+ var properties = CommonRunHelpers.GetGlobalPropertiesFromArgs(MSBuildArgs);
+ selector.InvalidateGlobalProperties(properties);
+ }
+
+ // Step 2: Check if device is now pre-specified after framework selection
+ if (!ListDevices && hasDevice)
+ {
+ // Device was pre-specified, we can skip device selection
return true;
}
+ // Step 3: Select device if needed
+ if (selector.TrySelectDevice(
+ ListDevices,
+ NoRestore,
+ out string? selectedDevice,
+ out string? runtimeIdentifier,
+ out _restoreDoneForDeviceSelection))
+ {
+ // If a device was selected (either by user or by prompt), apply it to MSBuildArgs
+ if (selectedDevice is not null)
+ {
+ var properties = new Dictionary { { "Device", selectedDevice } };
+
+ // If the device provided a RuntimeIdentifier, add it too
+ if (!string.IsNullOrEmpty(runtimeIdentifier))
+ {
+ properties["RuntimeIdentifier"] = runtimeIdentifier;
+
+ // If the device added a RuntimeIdentifier, we need to re-restore with that RID
+ // because the previous restore (if any) didn't include it
+ _restoreDoneForDeviceSelection = false;
+ }
+
+ var additionalProperties = new ReadOnlyDictionary(properties);
+ MSBuildArgs = MSBuildArgs.CloneWithAdditionalProperties(additionalProperties);
+ }
+
+ // If ListDevices was set, we return true but the caller will exit after listing
+ return !ListDevices;
+ }
+
return false;
}
@@ -238,8 +354,8 @@ private bool TrySelectTargetFrameworkForFileBasedProject()
return true; // Not multi-targeted
}
- // Use TargetFrameworkSelector to handle multi-target selection (or single framework selection)
- if (TargetFrameworkSelector.TrySelectTargetFramework(frameworks, Interactive, out string? selectedFramework))
+ // Use RunCommandSelector to handle multi-target selection (or single framework selection)
+ if (RunCommandSelector.TrySelectTargetFramework(frameworks, Interactive, out string? selectedFramework))
{
ApplySelectedFramework(selectedFramework);
return true;
@@ -375,7 +491,7 @@ private void EnsureProjectIsBuilt(out Func?
projectBuilder = null;
buildResult = new RestoringCommand(
MSBuildArgs.CloneWithExplicitArgs([ProjectFileFullPath, .. MSBuildArgs.OtherMSBuildArgs]),
- NoRestore,
+ NoRestore || _restoreDoneForDeviceSelection,
advertiseWorkloadUpdates: false
).Execute();
}
@@ -435,7 +551,7 @@ private MSBuildArgs SetupSilentBuildArgs(MSBuildArgs msbuildArgs)
}
}
- private ICommand GetTargetCommandForProject(ProjectLaunchProfile? launchSettings, Func? projectFactory, RunProperties? cachedRunProperties)
+ private ICommand GetTargetCommandForProject(ProjectLaunchProfile? launchSettings, Func? projectFactory, RunProperties? cachedRunProperties, FacadeLogger? logger)
{
ICommand command;
if (cachedRunProperties != null)
@@ -456,19 +572,10 @@ private ICommand GetTargetCommandForProject(ProjectLaunchProfile? launchSettings
else
{
Reporter.Verbose.WriteLine("Getting target command: evaluating project.");
- FacadeLogger? logger = LoggerUtility.DetermineBinlogger([.. MSBuildArgs.OtherMSBuildArgs], "dotnet-run");
- ProjectInstance project;
- try
- {
- project = EvaluateProject(ProjectFileFullPath, projectFactory, MSBuildArgs, logger);
- ValidatePreconditions(project);
- InvokeRunArgumentsTarget(project, NoBuild, logger, MSBuildArgs);
- }
- finally
- {
- logger?.ReallyShutdown();
- }
+ var project = EvaluateProject(ProjectFileFullPath, projectFactory, MSBuildArgs, logger);
+ ValidatePreconditions(project);
+ InvokeRunArgumentsTarget(project, NoBuild, logger, MSBuildArgs);
var runProperties = RunProperties.FromProject(project).WithApplicationArguments(ApplicationArgs);
command = CreateCommandFromRunProperties(runProperties);
@@ -775,6 +882,8 @@ public static RunCommand FromParseResult(ParseResult parseResult)
launchProfile: launchProfile,
noLaunchProfile: parseResult.HasOption(definition.NoLaunchProfileOption),
noLaunchProfileArguments: parseResult.HasOption(definition.NoLaunchProfileArgumentsOption),
+ device: parseResult.GetValue(definition.DeviceOption),
+ listDevices: parseResult.HasOption(definition.ListDevicesOption),
noRestore: parseResult.HasOption(definition.NoRestoreOption) || parseResult.HasOption(definition.NoBuildOption),
noCache: parseResult.HasOption(definition.NoCacheOption),
interactive: parseResult.GetValue(definition.InteractiveOption),
diff --git a/src/Cli/dotnet/Commands/Run/RunCommandSelector.cs b/src/Cli/dotnet/Commands/Run/RunCommandSelector.cs
new file mode 100644
index 000000000000..b2016b765bf4
--- /dev/null
+++ b/src/Cli/dotnet/Commands/Run/RunCommandSelector.cs
@@ -0,0 +1,511 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Exceptions;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Framework;
+using Microsoft.DotNet.Cli.Utils;
+using Spectre.Console;
+
+namespace Microsoft.DotNet.Cli.Commands.Run;
+
+///
+/// Handles target framework and device selection for dotnet run.
+/// Caches the project instance to avoid reloading it multiple times.
+///
+internal sealed class RunCommandSelector : IDisposable
+{
+ // Spectre.Console markup color constants
+ private const string CyanMarkup = "[cyan]";
+ private const string GrayMarkup = "[gray]";
+ private const string EndMarkup = "[/]";
+
+ private readonly string _projectFilePath;
+ private readonly Dictionary _globalProperties;
+ private readonly FacadeLogger? _binaryLogger;
+ private readonly bool _isInteractive;
+ private readonly MSBuildArgs _msbuildArgs;
+
+ private ProjectCollection? _collection;
+ private Microsoft.Build.Evaluation.Project? _project;
+
+ ///
+ /// Gets whether the selector has a valid project that can be evaluated.
+ /// This is false for .sln files or other invalid project files.
+ ///
+ public bool HasValidProject { get; private set; }
+
+ /// Path to the project file to evaluate
+ /// Whether to prompt the user for selections
+ /// MSBuild arguments containing properties and verbosity settings
+ /// Optional binary logger for MSBuild operations. The logger will not be disposed by this class.
+ public RunCommandSelector(
+ string projectFilePath,
+ bool isInteractive,
+ MSBuildArgs msbuildArgs,
+ FacadeLogger? binaryLogger = null)
+ {
+ _projectFilePath = projectFilePath;
+ _globalProperties = CommonRunHelpers.GetGlobalPropertiesFromArgs(msbuildArgs);
+ _isInteractive = isInteractive;
+ _msbuildArgs = msbuildArgs;
+ _binaryLogger = binaryLogger;
+ }
+
+ ///
+ /// Evaluates the project to determine if target framework selection is needed.
+ /// If the project has multiple target frameworks and none was specified, prompts the user to select one.
+ ///
+ /// The selected target framework, or null if not needed
+ /// True if we should continue, false if we should exit with error
+ public bool TrySelectTargetFramework(out string? selectedFramework)
+ {
+ selectedFramework = null;
+
+ // If a framework is already specified, no need to prompt
+ if (_globalProperties.TryGetValue("TargetFramework", out var existingFramework) && !string.IsNullOrWhiteSpace(existingFramework))
+ {
+ return true;
+ }
+
+ // Evaluate the project to get TargetFrameworks
+ if (!OpenProjectIfNeeded(out var projectInstance))
+ {
+ // Invalid project file, return true to continue for normal error handling
+ return true;
+ }
+ string targetFrameworks = projectInstance.GetPropertyValue("TargetFrameworks");
+
+ // If there's no TargetFrameworks property or only one framework, no selection needed
+ if (string.IsNullOrWhiteSpace(targetFrameworks))
+ {
+ return true;
+ }
+
+ // parse the TargetFrameworks property and make sure to account for any additional whitespace
+ // users may have added for formatting reasons.
+ var frameworks = targetFrameworks.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+
+ return TrySelectTargetFramework(frameworks, _isInteractive, out selectedFramework);
+ }
+
+ ///
+ /// Invalidates the loaded project with updated global properties.
+ /// This is needed after framework selection to get the correct device list for that framework.
+ ///
+ public void InvalidateGlobalProperties(Dictionary updatedProperties)
+ {
+ // Update our stored global properties
+ foreach (var (key, value) in updatedProperties)
+ {
+ _globalProperties[key] = value;
+ }
+
+ // Dispose existing project to force re-evaluation
+ _project = null;
+ _collection?.Dispose();
+ _collection = null;
+ HasValidProject = false;
+ }
+
+ ///
+ /// Opens the project if it hasn't been opened yet.
+ ///
+ private bool OpenProjectIfNeeded([NotNullWhen(true)] out ProjectInstance? projectInstance)
+ {
+ if (_project is not null)
+ {
+ // Create a fresh ProjectInstance for each build operation
+ // to avoid accumulating state (existing item groups) from previous builds
+ projectInstance = _project.CreateProjectInstance();
+ HasValidProject = true;
+ return true;
+ }
+
+ try
+ {
+ _collection = new ProjectCollection(
+ globalProperties: _globalProperties,
+ loggers: GetLoggers(),
+ toolsetDefinitionLocations: ToolsetDefinitionLocations.Default);
+ _project = _collection.LoadProject(_projectFilePath);
+ projectInstance = _project.CreateProjectInstance();
+ HasValidProject = true;
+ return true;
+ }
+ catch (InvalidProjectFileException)
+ {
+ // Invalid project file, return false
+ projectInstance = null;
+ HasValidProject = false;
+ return false;
+ }
+ }
+
+ public void Dispose()
+ {
+ // NOTE: _binaryLogger is not disposed here because it is *owned* by the caller
+ _collection?.Dispose();
+ }
+
+ ///
+ /// Handles target framework selection when given an array of frameworks.
+ /// If there's only one framework, selects it automatically.
+ /// If there are multiple frameworks, prompts the user (interactive) or shows an error (non-interactive).
+ ///
+ /// Array of target frameworks to choose from
+ /// Whether we're running in interactive mode (can prompt user)
+ /// The selected target framework, or null if selection was cancelled
+ /// True if we should continue, false if we should exit with error
+ public static bool TrySelectTargetFramework(string[] frameworks, bool isInteractive, out string? selectedFramework)
+ {
+ // If there's only one framework in the TargetFrameworks, we do need to pick it to force the subsequent builds/evaluations
+ // to act against the correct 'view' of the project
+ if (frameworks.Length == 1)
+ {
+ selectedFramework = frameworks[0];
+ return true;
+ }
+
+ if (isInteractive)
+ {
+ selectedFramework = PromptForTargetFramework(frameworks);
+ return selectedFramework != null;
+ }
+ else
+ {
+ Reporter.Error.WriteLine(string.Format(CliCommandStrings.RunCommandExceptionUnableToRunSpecifyFramework, "--framework"));
+ Reporter.Error.WriteLine();
+ Reporter.Error.WriteLine(CliCommandStrings.RunCommandAvailableTargetFrameworks);
+ Reporter.Error.WriteLine();
+
+ for (int i = 0; i < frameworks.Length; i++)
+ {
+ Reporter.Error.WriteLine($" {i + 1}. {frameworks[i]}");
+ }
+
+ Reporter.Error.WriteLine();
+ Reporter.Error.WriteLine($"{CliCommandStrings.RunCommandExampleText}: dotnet run --framework {frameworks[0]}");
+ Reporter.Error.WriteLine();
+ selectedFramework = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Prompts the user to select a target framework from the available options using Spectre.Console.
+ ///
+ private static string? PromptForTargetFramework(string[] frameworks)
+ {
+ try
+ {
+ var prompt = new SelectionPrompt()
+ .Title($"{CyanMarkup}{Markup.Escape(CliCommandStrings.RunCommandSelectTargetFrameworkPrompt)}{EndMarkup}")
+ .PageSize(10)
+ .MoreChoicesText($"{GrayMarkup}({Markup.Escape(CliCommandStrings.RunCommandMoreFrameworksText)}){EndMarkup}")
+ .AddChoices(frameworks)
+ .EnableSearch()
+ .SearchPlaceholderText(CliCommandStrings.RunCommandSearchPlaceholderText);
+
+ return Spectre.Console.AnsiConsole.Prompt(prompt);
+ }
+ catch (Exception)
+ {
+ // If Spectre.Console fails (e.g., terminal doesn't support it), return null
+ return null;
+ }
+ }
+
+ ///
+ /// Represents a device item returned from the ComputeAvailableDevices MSBuild target.
+ ///
+ public record DeviceItem(string Id, string? Description, string? Type, string? Status, string? RuntimeIdentifier);
+
+ ///
+ /// Computes available devices by calling the ComputeAvailableDevices MSBuild target if it exists.
+ ///
+ /// Whether restore should be skipped before computing devices
+ /// List of available devices if the target exists, null otherwise
+ /// True if restore was performed, false otherwise
+ /// True if the target was found and executed, false otherwise
+ public bool TryComputeAvailableDevices(bool noRestore, out List? devices, out bool restoreWasPerformed)
+ {
+ devices = null;
+ restoreWasPerformed = false;
+
+ if (!OpenProjectIfNeeded(out var projectInstance))
+ {
+ // Invalid project file, return false
+ return false;
+ }
+
+ // Check if the ComputeAvailableDevices target exists
+ if (!projectInstance.Targets.ContainsKey(Constants.ComputeAvailableDevices))
+ {
+ return false;
+ }
+
+ // If restore is allowed, run restore first so device computation sees the restored assets
+ if (!noRestore)
+ {
+ // Run the Restore target
+ var restoreResult = projectInstance.Build(
+ targets: ["Restore"],
+ loggers: GetLoggers(),
+ remoteLoggers: null,
+ out _);
+ if (!restoreResult)
+ {
+ return false;
+ }
+
+ restoreWasPerformed = true;
+ }
+
+ // Build the target
+ var buildResult = projectInstance.Build(
+ targets: [Constants.ComputeAvailableDevices],
+ loggers: GetLoggers(),
+ remoteLoggers: null,
+ out var targetOutputs);
+
+ if (!buildResult)
+ {
+ return false;
+ }
+
+ // Get the Devices items from the target output
+ if (!targetOutputs.TryGetValue(Constants.ComputeAvailableDevices, out var targetResult))
+ {
+ return false;
+ }
+
+ devices = new(targetResult.Items.Length);
+
+ foreach (var item in targetResult.Items)
+ {
+ devices.Add(new DeviceItem(
+ item.ItemSpec,
+ item.GetMetadata("Description"),
+ item.GetMetadata("Type"),
+ item.GetMetadata("Status"),
+ item.GetMetadata("RuntimeIdentifier")
+ ));
+ }
+
+ return true;
+ }
+
+ ///
+ /// Attempts to select a device for running the application.
+ /// If devices are available and none was specified, prompts the user to select one (interactive mode)
+ /// or shows an error (non-interactive mode).
+ ///
+ /// Whether to list devices and exit
+ /// Whether restore should be skipped
+ /// The selected device, or null if not needed
+ /// The RuntimeIdentifier for the selected device, or null if not provided
+ /// True if restore was performed, false otherwise
+ /// True if we should continue, false if we should exit
+ public bool TrySelectDevice(
+ bool listDevices,
+ bool noRestore,
+ out string? selectedDevice,
+ out string? runtimeIdentifier,
+ out bool restoreWasPerformed)
+ {
+ selectedDevice = null;
+ runtimeIdentifier = null;
+ restoreWasPerformed = false;
+
+ // Try to get available devices from the project
+ bool targetExists = TryComputeAvailableDevices(noRestore, out var devices, out restoreWasPerformed);
+
+ // If the target doesn't exist, continue without device selection
+ if (!targetExists)
+ {
+ // No device support in this project
+ return true;
+ }
+
+ // Target exists - check if we have devices
+ if (devices is null || devices.Count == 0)
+ {
+ if (listDevices)
+ {
+ Reporter.Output.WriteLine(CliCommandStrings.RunCommandNoDevicesAvailable);
+ return true;
+ }
+
+ // Target exists but no devices available - this is an error
+ Reporter.Error.WriteLine(CliCommandStrings.RunCommandNoDevicesAvailable);
+ return false;
+ }
+
+ // If listing devices, display them and exit
+ if (listDevices)
+ {
+ Reporter.Output.WriteLine(CliCommandStrings.RunCommandAvailableDevices);
+ Reporter.Output.WriteLine();
+
+ for (int i = 0; i < devices.Count; i++)
+ {
+ var device = devices[i];
+ var displayBuilder = new StringBuilder($" {i + 1}. {device.Id}");
+
+ if (!string.IsNullOrWhiteSpace(device.Description))
+ {
+ displayBuilder.Append($" - {device.Description}");
+ }
+
+ if (!string.IsNullOrWhiteSpace(device.Type))
+ {
+ displayBuilder.Append($" ({device.Type}");
+ if (!string.IsNullOrWhiteSpace(device.Status))
+ {
+ displayBuilder.Append($", {device.Status}");
+ }
+ displayBuilder.Append(')');
+ }
+ else if (!string.IsNullOrWhiteSpace(device.Status))
+ {
+ displayBuilder.Append($" ({device.Status})");
+ }
+
+ Reporter.Output.WriteLine(displayBuilder.ToString());
+ }
+
+ Reporter.Output.WriteLine();
+ Reporter.Output.WriteLine($"{CliCommandStrings.RunCommandExampleText}: dotnet run --device {ArgumentEscaper.EscapeSingleArg(devices[0].Id)}");
+ Reporter.Output.WriteLine();
+ return true;
+ }
+
+ // If there's only one device, automatically select it (similar to single framework selection)
+ if (devices.Count == 1)
+ {
+ selectedDevice = devices[0].Id;
+ runtimeIdentifier = devices[0].RuntimeIdentifier;
+ return true;
+ }
+
+ if (_isInteractive)
+ {
+ var deviceItem = PromptForDevice(devices);
+ if (deviceItem is null)
+ {
+ return false;
+ }
+
+ selectedDevice = deviceItem.Id;
+ runtimeIdentifier = deviceItem.RuntimeIdentifier;
+ return true;
+ }
+ else
+ {
+ Reporter.Error.WriteLine(string.Format(CliCommandStrings.RunCommandExceptionUnableToRunSpecifyDevice, "--device"));
+ Reporter.Error.WriteLine();
+ Reporter.Error.WriteLine(CliCommandStrings.RunCommandAvailableDevices);
+ Reporter.Error.WriteLine();
+
+ for (int i = 0; i < devices.Count; i++)
+ {
+ var device = devices[i];
+ var displayText = $" {i + 1}. {device.Id}";
+
+ if (!string.IsNullOrWhiteSpace(device.Description))
+ {
+ displayText += $" - {device.Description}";
+ }
+
+ Reporter.Error.WriteLine(displayText);
+ }
+
+ Reporter.Error.WriteLine();
+ Reporter.Error.WriteLine($"{CliCommandStrings.RunCommandExampleText}: dotnet run --device {ArgumentEscaper.EscapeSingleArg(devices[0].Id)}");
+ Reporter.Error.WriteLine();
+ return false;
+ }
+ }
+
+ ///
+ /// Prompts the user to select a device from the available options using Spectre.Console.
+ ///
+ private static DeviceItem? PromptForDevice(List devices)
+ {
+ List<(string Display, DeviceItem Device)> choices = new(devices.Count);
+ foreach (var d in devices)
+ {
+ var display = d.Id;
+ if (!string.IsNullOrWhiteSpace(d.Description))
+ {
+ display += $" - {d.Description}";
+ }
+ choices.Add((display, d));
+ }
+
+ try
+ {
+ var prompt = new SelectionPrompt<(string Display, DeviceItem Device)>()
+ .Title($"{CyanMarkup}{Markup.Escape(CliCommandStrings.RunCommandSelectDevicePrompt)}{EndMarkup}")
+ .PageSize(10)
+ .MoreChoicesText($"{GrayMarkup}({Markup.Escape(CliCommandStrings.RunCommandMoreDevicesText)}){EndMarkup}")
+ .AddChoices(choices)
+ .UseConverter(choice => choice.Display)
+ .EnableSearch()
+ .SearchPlaceholderText(CliCommandStrings.RunCommandSearchPlaceholderText);
+
+ var (Display, Device) = Spectre.Console.AnsiConsole.Prompt(prompt);
+ return Device;
+ }
+ catch (Exception)
+ {
+ // If Spectre.Console fails (e.g., terminal doesn't support it), return null
+ return null;
+ }
+ }
+
+ ///
+ /// Attempts to deploy to a device by calling the DeployToDevice MSBuild target if it exists.
+ /// This reuses the already-loaded project instance for performance.
+ ///
+ /// True if deployment succeeded or was skipped (no target), false if deployment failed
+ public bool TryDeployToDevice()
+ {
+ if (!OpenProjectIfNeeded(out var projectInstance))
+ {
+ // Invalid project file
+ return false;
+ }
+
+ // Check if the DeployToDevice target exists in the project
+ if (!projectInstance.Targets.ContainsKey(Constants.DeployToDevice))
+ {
+ // Target doesn't exist, skip deploy step
+ return true;
+ }
+
+ // Build the DeployToDevice target
+ var buildResult = projectInstance.Build(
+ targets: [Constants.DeployToDevice],
+ loggers: GetLoggers(),
+ remoteLoggers: null,
+ out _);
+
+ return buildResult;
+ }
+
+ ///
+ /// Gets the list of loggers to use for MSBuild operations.
+ /// Creates a fresh console logger each time to avoid disposal issues when calling Build() multiple times.
+ ///
+ private IEnumerable GetLoggers()
+ {
+ if (_binaryLogger is not null)
+ yield return _binaryLogger;
+ yield return CommonRunHelpers.GetConsoleLogger(_msbuildArgs);
+ }
+}
diff --git a/src/Cli/dotnet/Commands/Run/TargetFrameworkSelector.cs b/src/Cli/dotnet/Commands/Run/TargetFrameworkSelector.cs
deleted file mode 100644
index 82f8d7c152ba..000000000000
--- a/src/Cli/dotnet/Commands/Run/TargetFrameworkSelector.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.Build.Evaluation;
-using Microsoft.Build.Exceptions;
-using Microsoft.DotNet.Cli.Utils;
-using Spectre.Console;
-
-namespace Microsoft.DotNet.Cli.Commands.Run;
-
-internal static class TargetFrameworkSelector
-{
- ///
- /// Evaluates the project to determine if target framework selection is needed.
- /// If the project has multiple target frameworks and none was specified, prompts the user to select one.
- ///
- /// Path to the project file
- /// Global properties for MSBuild evaluation
- /// Whether we're running in interactive mode (can prompt user)
- /// The selected target framework, or null if not needed
- /// True if we should continue, false if we should exit with error
- public static bool TrySelectTargetFramework(
- string projectFilePath,
- Dictionary globalProperties,
- bool isInteractive,
- out string? selectedFramework)
- {
- selectedFramework = null;
-
- // If a framework is already specified, no need to prompt
- if (globalProperties.TryGetValue("TargetFramework", out var existingFramework) && !string.IsNullOrWhiteSpace(existingFramework))
- {
- return true;
- }
-
- // Evaluate the project to get TargetFrameworks
- string targetFrameworks;
- try
- {
- using var collection = new ProjectCollection(globalProperties: globalProperties);
- var project = collection.LoadProject(projectFilePath);
- targetFrameworks = project.GetPropertyValue("TargetFrameworks");
- }
- catch (InvalidProjectFileException)
- {
- // Invalid project file, return true to continue for normal error handling
- return true;
- }
-
- // If there's no TargetFrameworks property or only one framework, no selection needed
- if (string.IsNullOrWhiteSpace(targetFrameworks))
- {
- return true;
- }
-
- // parse the TargetFrameworks property and make sure to account for any additional whitespace
- // users may have added for formatting reasons.
- var frameworks = targetFrameworks.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
-
- return TrySelectTargetFramework(frameworks, isInteractive, out selectedFramework);
- }
-
- ///
- /// Handles target framework selection when given an array of frameworks.
- /// If there's only one framework, selects it automatically.
- /// If there are multiple frameworks, prompts the user (interactive) or shows an error (non-interactive).
- ///
- /// Array of target frameworks to choose from
- /// Whether we're running in interactive mode (can prompt user)
- /// The selected target framework, or null if selection was cancelled
- /// True if we should continue, false if we should exit with error
- public static bool TrySelectTargetFramework(string[] frameworks, bool isInteractive, out string? selectedFramework)
- {
- // If there's only one framework in the TargetFrameworks, we do need to pick it to force the subsequent builds/evaluations
- // to act against the correct 'view' of the project
- if (frameworks.Length == 1)
- {
- selectedFramework = frameworks[0];
- return true;
- }
-
- if (isInteractive)
- {
- selectedFramework = PromptForTargetFramework(frameworks);
- return selectedFramework != null;
- }
- else
- {
- Reporter.Error.WriteLine(string.Format(CliCommandStrings.RunCommandExceptionUnableToRunSpecifyFramework, "--framework"));
- Reporter.Error.WriteLine();
- Reporter.Error.WriteLine(CliCommandStrings.RunCommandAvailableTargetFrameworks);
- Reporter.Error.WriteLine();
-
- for (int i = 0; i < frameworks.Length; i++)
- {
- Reporter.Error.WriteLine($" {i + 1}. {frameworks[i]}");
- }
-
- Reporter.Error.WriteLine();
- Reporter.Error.WriteLine($"{CliCommandStrings.RunCommandExampleText}: dotnet run --framework {frameworks[0]}");
- Reporter.Error.WriteLine();
- selectedFramework = null;
- return false;
- }
- }
-
- ///
- /// Prompts the user to select a target framework from the available options using Spectre.Console.
- ///
- private static string? PromptForTargetFramework(string[] frameworks)
- {
- try
- {
- var prompt = new SelectionPrompt()
- .Title($"[cyan]{Markup.Escape(CliCommandStrings.RunCommandSelectTargetFrameworkPrompt)}[/]")
- .PageSize(10)
- .MoreChoicesText($"[grey]({Markup.Escape(CliCommandStrings.RunCommandMoreFrameworksText)})[/]")
- .AddChoices(frameworks)
- .EnableSearch()
- .SearchPlaceholderText(CliCommandStrings.RunCommandSearchPlaceholderText);
-
- return Spectre.Console.AnsiConsole.Prompt(prompt);
- }
- catch (Exception)
- {
- // If Spectre.Console fails (e.g., terminal doesn't support it), return null
- return null;
- }
- }
-}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
index 25de438df13c..aca54ec20616 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
@@ -57,6 +57,21 @@
AutořiTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Sestaví projekt .NET.
@@ -902,7 +917,7 @@ Nástroj {1} (verze {2}) se úspěšně nainstaloval. Do souboru manifestu {3} s
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- Nejsou nainstalované žádné úlohy, nic se nedá opravit. Pokud chcete najít úlohy, které se mají nainstalovat, spusťte vyhledávání úloh dotnet.
+ Nejsou nainstalované žádné úlohy, nic se nedá opravit. Pokud chcete najít úlohy, které se mají nainstalovat, spusťte vyhledávání úloh dotnet.
@@ -1219,7 +1234,7 @@ Nástroj {1} (verze {2}) se úspěšně nainstaloval. Do souboru manifestu {3} s
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Zadejte výstupní adresář (stisknutím klávesy Enter použijete výchozí hodnotu: {0}, adresář nesmí existovat):
+ Zadejte výstupní adresář ({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ Nástroj {1} (verze {2}) se úspěšně nainstaloval. Do souboru manifestu {3} s
Vrací se zpět instalace balíčku {0}…
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Dostupné cílové architektury:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Nástroj {1} (verze {2}) se úspěšně nainstaloval. Do souboru manifestu {3} s
Sestavování...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.Spuštění cíle {0} ke zjištění příkazů spuštění pro tento projekt se nezdařilo. Opravte chyby a upozornění a spusťte je znovu.
@@ -1344,7 +1369,7 @@ Nástroj {1} (verze {2}) se úspěšně nainstaloval. Do souboru manifestu {3} s
Example
- Příklad
+ Example
@@ -1381,12 +1406,17 @@ Nástroj {1} (verze {2}) se úspěšně nainstaloval. Do souboru manifestu {3} s
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- V projektu {0} nelze pokračovat.
-Ujistěte se, že máte spustitelný typ projektu.
-Spustitelný projekt by měl cílit na spustitelný TFM (například net{1}) a mít OutputType Exe.
-Aktuální OutputType je {2}.
+ Projekt se nedá spustit.
+Ověřte prosím, že máte spustitelný typ projektu, a zajistěte, aby tento projekt podporoval {0}.
+Cílem spustitelného projektu by mělo být TFM (například net5.0) a jeho OutputType by měl být Exe.
+Aktuální {1} je {2}.{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Cílem projektu je více architektur. Pomocí parametru {0} určete, která architektura se má spustit.
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Posunutím nahoru a dolů zobrazíte další architektury.
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Cílem projektu je více architektur. Pomocí parametru {0} určete, která arch
Type to search
- Zadejte hledaný text
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Vyberte cílovou architekturu, která se má spustit:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
index ac5454709239..553a73dc90fc 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
@@ -57,6 +57,21 @@
AutorenTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Hiermit wird ein .NET-Projekt erstellt.
@@ -902,7 +917,7 @@ Das Tool "{1}" (Version {2}) wurde erfolgreich installiert. Der Eintrag wird der
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- Es sind keine Workloads installiert, es ist keine Reparatur erforderlich. Führen Sie „dotnet workload search“ aus, um zu installierende Workloads zu finden.
+ Es sind keine Workloads installiert, es ist keine Reparatur erforderlich. Führen Sie „dotnet workload search“ aus, um zu installierende Workloads zu finden.
@@ -1219,7 +1234,7 @@ Das Tool "{1}" (Version {2}) wurde erfolgreich installiert. Der Eintrag wird der
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Geben Sie das Ausgabeverzeichnis an (drücken Sie die EINGABETASTE, um die Standardeinstellung zu verwenden: „{0}“, das Verzeichnis darf nicht vorhanden sein):
+ Ausgabeverzeichnis ({0}) angeben:{0} is the default value
@@ -1327,9 +1342,14 @@ Das Tool "{1}" (Version {2}) wurde erfolgreich installiert. Der Eintrag wird der
Für die Installation von {0} wird ein Rollback ausgeführt...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Verfügbare Zielframeworks:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Das Tool "{1}" (Version {2}) wurde erfolgreich installiert. Der Eintrag wird der
Buildvorgang wird ausgeführt...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.Das {0} Ziel ausführen, um zu ermitteln, dass ein Fehler bei den Ausführungsbefehlen für dieses Projekt aufgetreten ist. Beheben Sie die Fehler und Warnungen, und führen Sie dies erneut aus.
@@ -1344,7 +1369,7 @@ Das Tool "{1}" (Version {2}) wurde erfolgreich installiert. Der Eintrag wird der
Example
- Beispiel
+ Example
@@ -1381,12 +1406,17 @@ Das Tool "{1}" (Version {2}) wurde erfolgreich installiert. Der Eintrag wird der
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- Ihr Projekt „{0}“ kann nicht fortgesetzt werden.
-Stellen Sie sicher, dass der Projekttyp ausführbar ist.
-Ein ausführbares Projekt muss ein ausführbares TFM (z. B. net{1}) und den OutputType „Exe“ verwenden.
-Der aktuelle OutputType lautet „{2}“.
+ Ihr Projekt kann nicht ausgeführt werden.
+Stellen Sie sicher, dass der Projekttyp ausführbar ist und "{0}" dieses Projekt unterstützt.
+Ein ausführbares Projekt muss ein ausführbares TFM (z. B. net5.0) und den OutputType "Exe" verwenden.
+{1} lautet aktuell "{2}".{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Ihr Projekt verwendet mehrere Zielframeworks. Geben Sie über "{0}" an, welches Framework ausgeführt werden soll.
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Nach oben und unten bewegen, um weitere Frameworks anzuzeigen
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Ihr Projekt verwendet mehrere Zielframeworks. Geben Sie über "{0}" an, welches
Type to search
- Zum Suchen eingeben
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Wählen Sie das auszuführende Zielframework aus:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
index 8316f3a8bc8c..91c32ff85daa 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
@@ -57,6 +57,21 @@
AutoresTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Compila un proyecto de .NET.
@@ -902,7 +917,7 @@ La herramienta "{1}" (versión "{2}") se instaló correctamente. Se ha agregado
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- No hay cargas de trabajo instaladas, no hay nada que reparar. Ejecute "dotnet workload search" para buscar las cargas de trabajo que se van a instalar.
+ No hay cargas de trabajo instaladas, no hay nada que reparar. Ejecute "dotnet workload search" para buscar las cargas de trabajo que se van a instalar.
@@ -1219,7 +1234,7 @@ La herramienta "{1}" (versión "{2}") se instaló correctamente. Se ha agregado
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Especifique el directorio de salida (presione Entrar para el valor predeterminado: ''{0}, el directorio no debe existir):
+ Especifique el directorio de salida ({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ La herramienta "{1}" (versión "{2}") se instaló correctamente. Se ha agregado
Revirtiendo el paquete {0} de la instalación...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Plataformas de destino disponibles:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ La herramienta "{1}" (versión "{2}") se instaló correctamente. Se ha agregado
Compilando...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.Error al ejecutar el destino {0} para detectar comandos de ejecución para este proyecto. Corrija los errores y advertencias y vuelva a ejecutarlo.
@@ -1344,7 +1369,7 @@ La herramienta "{1}" (versión "{2}") se instaló correctamente. Se ha agregado
Example
- Ejemplo
+ Example
@@ -1362,7 +1387,7 @@ La herramienta "{1}" (versión "{2}") se instaló correctamente. Se ha agregado
Cannot use launch profile '{0}' because the launch settings file could not be located. Locations tried:
{1}
- No se puede usar el perfil de inicio '{0}' porque no se pudo localizar el archivo de configuración de inicio. Ubicaciones probadas:
+ No se puede usar el perfil de inicio '{0}' porque no se pudo localizar el archivo de configuración de inicio. Ubicaciones probadas:
{1}
@@ -1381,12 +1406,17 @@ La herramienta "{1}" (versión "{2}") se instaló correctamente. Se ha agregado
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- No se puede continuar con el proyecto '{0}'.
-Asegúrese de que tiene un tipo de proyecto que se puede ejecutar.
-Un proyecto ejecutable debe tener como destino un TFM ejecutable (por ejemplo, net{1}) y tener OutputType 'Exe'.
-El OutputType actual es '{2}'.
+ No se puede ejecutar el proyecto.
+Asegúrese de tener un tipo de proyecto ejecutable y asegúrese de que "{0}" admita este proyecto.
+Un proyecto ejecutable debe tener como destino un TFM ejecutable (por ejemplo, net5.0) y tener como OutputType "Exe".
+El valor actual de {1} es "{2}".{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Su proyecto tiene como destino varias plataformas. Especifique la que quiere usar mediante "{0}".
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Subir y bajar para mostrar más marcos
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Su proyecto tiene como destino varias plataformas. Especifique la que quiere usa
Type to search
- Escriba para buscar
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Seleccione la plataforma de destino que se va a ejecutar:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
index 76d33a50c526..63eae5969a2f 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
@@ -57,6 +57,21 @@
AuteursTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Générez un projet .NET.
@@ -902,7 +917,7 @@ L'outil '{1}' (version '{2}') a été correctement installé. L'entrée est ajou
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- Aucune charge de travail n’est installée, rien à réparer. Exécutez « recherche de charge de travail dotnet » pour trouver les charges de travail à installer.
+ Aucune charge de travail n’est installée, rien à réparer. Exécutez « recherche de charge de travail dotnet » pour trouver les charges de travail à installer.
@@ -1219,7 +1234,7 @@ L'outil '{1}' (version '{2}') a été correctement installé. L'entrée est ajou
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Spécifiez le répertoire de sortie (appuyez sur Entrée pour utiliser la valeur par défaut : « {0} », le répertoire ne doit pas exister) :
+ Spécifiez le répertoire de sortie ({0}) :{0} is the default value
@@ -1327,9 +1342,14 @@ L'outil '{1}' (version '{2}') a été correctement installé. L'entrée est ajou
Annulation de l'installation {0}...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Frameworks cibles disponibles :
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ L'outil '{1}' (version '{2}') a été correctement installé. L'entrée est ajou
Génération...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.L’exécution de la {0} cible pour découvrir les commandes d’exécution a échoué pour ce projet. Corrigez les erreurs et les avertissements, puis réexécutez.
@@ -1344,7 +1369,7 @@ L'outil '{1}' (version '{2}') a été correctement installé. L'entrée est ajou
Example
- Exemple
+ Example
@@ -1362,7 +1387,7 @@ L'outil '{1}' (version '{2}') a été correctement installé. L'entrée est ajou
Cannot use launch profile '{0}' because the launch settings file could not be located. Locations tried:
{1}
- Impossible d’utiliser le profil de lancement « {0} », car le fichier de paramètres de lancement est introuvable. Emplacements essayés :
+ Impossible d’utiliser le profil de lancement « {0} », car le fichier de paramètres de lancement est introuvable. Emplacements essayés :
{1}
@@ -1381,12 +1406,17 @@ L'outil '{1}' (version '{2}') a été correctement installé. L'entrée est ajou
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- Impossible de continuer avec le projet « {0} ».
-Vérifiez que vous avez un type de projet exécutable.
-Un projet exécutable doit cibler un TFM exécutable (par exemple, net{1}) et avoir OutputType « Exe ».
-Le type de sortie actuel (OutputType) est « {2} ».
+ Impossible d'exécuter votre projet.
+Vérifiez que vous avez un type de projet exécutable et que '{0}' prend en charge ce projet.
+Un projet exécutable doit cibler un TFM exécutable (par exemple, net5.0) et avoir OutputType 'Exe'.
+Le {1} actuel est '{2}'.{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Votre projet cible plusieurs frameworks. Spécifiez le framework à exécuter à l'aide de '{0}'.
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Montez et descendez pour afficher plus de frameworks
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Votre projet cible plusieurs frameworks. Spécifiez le framework à exécuter à
Type to search
- Entrer le texte à rechercher
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Sélectionner le framework cible pour exécuter :
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
index 42862d54224e..916c4b11c60e 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
@@ -57,6 +57,21 @@
AutoriTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Compila un progetto .NET.
@@ -902,7 +917,7 @@ Lo strumento '{1}' versione '{2}' è stato installato. La voce è stata aggiunta
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- Nessun carico di lavoro installato, nulla da ripristinare. Eseguire 'ricerca del carico di lavoro DotNet' per trovare i carichi di lavoro da installare.
+ Nessun carico di lavoro installato, nulla da ripristinare. Eseguire 'ricerca del carico di lavoro DotNet' per trovare i carichi di lavoro da installare.
@@ -1219,7 +1234,7 @@ Lo strumento '{1}' versione '{2}' è stato installato. La voce è stata aggiunta
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Specificare la directory di output (premere INVIO per impostazione predefinita: '{0}', la directory non deve esistere):
+ Specifica la directory di output ({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ Lo strumento '{1}' versione '{2}' è stato installato. La voce è stata aggiunta
Rollback dell'installazione del pacchetto {0} in corso...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Framework di destinazione disponibili:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Lo strumento '{1}' versione '{2}' è stato installato. La voce è stata aggiunta
Compilazione...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.L'esecuzione della destinazione {0} per individuare i comandi di esecuzione non è riuscita per questo progetto. Correggere gli errori e gli avvisi ed eseguire di nuovo.
@@ -1344,7 +1369,7 @@ Lo strumento '{1}' versione '{2}' è stato installato. La voce è stata aggiunta
Example
- Esempio
+ Example
@@ -1362,7 +1387,7 @@ Lo strumento '{1}' versione '{2}' è stato installato. La voce è stata aggiunta
Cannot use launch profile '{0}' because the launch settings file could not be located. Locations tried:
{1}
- Non è possibile usare il profilo di avvio "{0}" perché il file delle impostazioni di avvio non è stato trovato. Posizioni tentate:
+ Non è possibile usare il profilo di avvio "{0}" perché il file delle impostazioni di avvio non è stato trovato. Posizioni tentate:
{1}
@@ -1381,12 +1406,17 @@ Lo strumento '{1}' versione '{2}' è stato installato. La voce è stata aggiunta
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- Non è possibile procedere con il progetto '{0}'.
-Assicurarsi che sia presente un tipo di progetto eseguibile.
-Un progetto eseguibile deve essere destinato a un TFM eseguibile, ad esempio net{1}, inoltre OutputType deve essere impostato su 'Exe'.
-L'OutputType corrente è '{2}'.
+ Non è possibile eseguire il progetto.
+Assicurarsi che sia presente un tipo di progetto eseguibile e che '{0}' supporti tale progetto.
+Un progetto eseguibile deve essere destinato a un TFM eseguibile, ad esempio net5.0, inoltre OutputType deve essere impostato su 'Exe'.
+Il valore corrente di {1} è '{2}'.{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Il progetto è destinato a più framework. Specificare il framework da eseguire con '{0}'.
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Spostarsi verso l'alto o verso il basso per visualizzare altri framework
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Il progetto è destinato a più framework. Specificare il framework da eseguire
Type to search
- Digita per cercare
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Selezionare il framework di destinazione da eseguire:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
index c3ea3a16264a..0f07011cd52d 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
@@ -57,6 +57,21 @@
作成者Table lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project..NET プロジェクトをビルドします。
@@ -902,7 +917,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- ワークロードがインストールされていないため、修復するものがありません。`dotnet ワークロード検索` を実行してインストールするワークロードを検索します。
+ ワークロードがインストールされていないため、修復するものがありません。`dotnet ワークロード検索` を実行してインストールするワークロードを検索します。
@@ -1219,7 +1234,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- 出力ディレクトリを指定します (Enter キーを押すと既定値に設定されます: '{0}'、ディレクトリは存在してはなりません):
+ 出力ディレクトリ ({0}) を指定します:{0} is the default value
@@ -1327,9 +1342,14 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
パック {0} のインストールをロールバックしています...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- 使用可能なターゲット フレームワーク:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
ビルドしています...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.このプロジェクトで実行コマンドを検出するための {0} ターゲットの実行に失敗しました。エラーと警告を修正して、もう一度実行してください。
@@ -1344,7 +1369,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Example
- 例
+ Example
@@ -1362,7 +1387,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Cannot use launch profile '{0}' because the launch settings file could not be located. Locations tried:
{1}
- 起動設定ファイルが見つからないため、起動プロファイル '{0}' を使用できません。試行された場所:
+ 起動設定ファイルが見つからないため、起動プロファイル '{0}' を使用できません。試行された場所:
{1}
@@ -1381,12 +1406,17 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- プロジェクト '{0}' を続行できません。
-実行可能なプロジェクト タイプがあることを確認します。
-実行可能なプロジェクトは実行可能な TFM (たとえば、net{1}) を対象としている必要があり、OutputType 'Exe' が必要です。
-現在の OutputType は '{2}' です。
+ プロジェクトを実行できません。
+プロジェクト タイプが実行可能であること、このプロジェクトが '{0}' でサポートされていることを確認してください。
+実行可能なプロジェクトは実行可能な TFM (たとえば、net5.0) を対象としている必要があり、OutputType 'Exe' が必要です。
+現在の {1} は '{2}' です。{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
プロジェクトは複数のフレームワークを対象としています。'{0}' を使用して、実行するフレームワークを指定してください。
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- 上下に移動して、さらに多くのフレームワークを表示
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Your project targets multiple frameworks. Specify which framework to run using '
Type to search
- 入力して検索します
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- 実行するターゲット フレームワークを選択してください:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
index a9b00d45f66b..20b68d1a3182 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
@@ -57,6 +57,21 @@
작성자Table lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project..NET 프로젝트를 빌드합니다.
@@ -902,7 +917,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- 워크로드가 설치되어 있지 않고 복구할 것도 없습니다. ‘dotnet 워크로드 검색’을 실행하여 설치할 워크로드를 찾으세요.
+ 워크로드가 설치되어 있지 않고 복구할 것도 없습니다. ‘dotnet 워크로드 검색’을 실행하여 설치할 워크로드를 찾으세요.
@@ -1219,7 +1234,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- 출력 디렉터리를 지정합니다(Enter 키를 누르면 '{0}' 기본값 사용, 기존 디렉터리가 없어야 함).
+ 출력 디렉터리 지정({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
팩 {0} 설치를 롤백 중...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- 사용 가능한 대상 프레임워크:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
빌드하는 중...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.이 프로젝트에 대해 실행 명령을 검색하기 위해 {0} 대상을 실행하지 못했습니다. 오류 및 경고를 수정하고 다시 실행합니다.
@@ -1344,7 +1369,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Example
- 예제
+ Example
@@ -1362,7 +1387,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Cannot use launch profile '{0}' because the launch settings file could not be located. Locations tried:
{1}
- 시작 설정 파일을 찾을 수 없으므로 시작 프로필 '{0}'을(를) 사용할 수 없습니다. 시도한 위치:
+ 시작 설정 파일을 찾을 수 없으므로 시작 프로필 '{0}'을(를) 사용할 수 없습니다. 시도한 위치:
{1}
@@ -1381,12 +1406,17 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- 프로젝트 '{0}'을(를) 진행할 수 없습니다.
-실행 가능한 프로젝트 형식이 있는지 확인하세요.
-실행 가능한 프로젝트는 실행 가능한 TFM(예: net{1})을(를) 대상으로 하고 OutputType 'Exe'가 있어야 합니다.
-현재 OutputType은(는) '{2}'입니다.
+ 프로젝트를 실행할 수 없습니다.
+실행 가능한 프로젝트 형식이 있고 '{0}'에서 이 프로젝트를 지원하는지 확인하세요.
+실행 가능한 프로젝트는 실행 가능한 TFM(예: net5.0)을 대상으로 하고 OutputType 'Exe'가 있어야 합니다.
+현재 {1}은(는) '{2}'입니다.{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
프로젝트에서 여러 프레임워크를 대상으로 합니다. '{0}'을(를) 사용하여 실행할 프레임워크를 지정하세요.
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- 더 많은 프레임워크를 보려면 위아래로 이동하세요.
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Your project targets multiple frameworks. Specify which framework to run using '
Type to search
- 검색할 형식
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- 실행할 대상 프레임워크 선택:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
index 7b0e2ff45a1f..dda65dfdf1e3 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
@@ -57,6 +57,21 @@
AutorzyTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Kompiluj projekt platformy .NET.
@@ -902,7 +917,7 @@ Narzędzie „{1}” (wersja „{2}”) zostało pomyślnie zainstalowane. Wpis
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- Nie zainstalowano żadnych obciążeń i nie ma nic do naprawienia. Uruchom polecenie „dotnet workload search”, aby znaleźć obciążenia do zainstalowania.
+ Nie zainstalowano żadnych obciążeń i nie ma nic do naprawienia. Uruchom polecenie „dotnet workload search”, aby znaleźć obciążenia do zainstalowania.
@@ -1219,7 +1234,7 @@ Narzędzie „{1}” (wersja „{2}”) zostało pomyślnie zainstalowane. Wpis
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Określ katalog wyjściowy (naciśnij Enter, aby użyć wartości domyślnej: „{0}”, katalog nie może istnieć):
+ Określ katalog wyjściowy ({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ Narzędzie „{1}” (wersja „{2}”) zostało pomyślnie zainstalowane. Wpis
Trwa wycofywanie instalacji paczki {0}.
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Dostępne docelowe struktury:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Narzędzie „{1}” (wersja „{2}”) zostało pomyślnie zainstalowane. Wpis
Trwa kompilowanie...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.Uruchomienie obiektu docelowego {0} w celu odnalezienia poleceń przebiegu dla tego projektu nie powiodło się. Usuń błędy i ostrzeżenia, a następnie uruchom ponownie.
@@ -1344,7 +1369,7 @@ Narzędzie „{1}” (wersja „{2}”) zostało pomyślnie zainstalowane. Wpis
Example
- Przykład
+ Example
@@ -1381,12 +1406,17 @@ Narzędzie „{1}” (wersja „{2}”) zostało pomyślnie zainstalowane. Wpis
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- Nie można kontynuować pracy z projektem „{0}”.
-Upewnij się, że masz typ projektu, który można uruchomić.
-Projekt, który można uruchomić, powinien być przeznaczony dla możliwego do uruchomienia monikera platformy docelowej (na przykład net{1}) i mieć typ OutputType „Exe”.
-Bieżący typ OutputType to „{2}”.
+ Nie można uruchomić projektu.
+Upewnij się, że używany typ projektu umożliwia uruchamianie oraz że element „{0}” obsługuje ten projekt.
+Projekt z możliwością uruchamiania musi mieć moniker TFM z możliwością uruchomienia (np. net5.0) i typ OutputType „Exe”.
+Bieżący element {1}: „{2}”.{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Projekt ma wiele platform docelowych. Określ platformę do uruchomienia przy użyciu elementu „{0}”.
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Przesuń w górę lub w dół, aby zobaczyć więcej struktur
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Projekt ma wiele platform docelowych. Określ platformę do uruchomienia przy u
Type to search
- Wpisz, aby wyszukać
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Wybierz docelową strukturę do uruchomienia:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
index 5da015345085..c32d0c5c5c99 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
@@ -57,6 +57,21 @@
AutoresTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Criar um projeto do .NET.
@@ -902,7 +917,7 @@ A ferramenta '{1}' (versão '{2}') foi instalada com êxito. A entrada foi adici
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- Nenhuma carga de trabalho instalada, nada para reparar. Execute a 'pesquisa de carga de trabalho dotnet' para encontrar cargas de trabalho a serem instaladas.
+ Nenhuma carga de trabalho instalada, nada para reparar. Execute a 'pesquisa de carga de trabalho dotnet' para encontrar cargas de trabalho a serem instaladas.
@@ -1219,7 +1234,7 @@ A ferramenta '{1}' (versão '{2}') foi instalada com êxito. A entrada foi adici
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Especifique o diretório de saída (pressione Enter para o padrão: '{0}', o diretório não deve existir):
+ Especificar o diretório de saída ({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ A ferramenta '{1}' (versão '{2}') foi instalada com êxito. A entrada foi adici
Revertendo o pacote {0} instalação...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Estruturas de destino disponíveis:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ A ferramenta '{1}' (versão '{2}') foi instalada com êxito. A entrada foi adici
Compilando...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.Falha na execução do destino {0} para descobrir comandos de execução para este projeto. Corrija os erros e avisos e execute novamente.
@@ -1344,7 +1369,7 @@ A ferramenta '{1}' (versão '{2}') foi instalada com êxito. A entrada foi adici
Example
- Exemplo
+ Example
@@ -1381,12 +1406,17 @@ A ferramenta '{1}' (versão '{2}') foi instalada com êxito. A entrada foi adici
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- Não é possível continuar com o projeto "{0}".
-Verifique se você tem um tipo de projeto executável.
-Um projeto executável deve ter como destino um TFM executável (por exemplo, net{1}) e ter OutputType "Exe".
-O OutputType atual é "{2}".
+ Não é possível executar o projeto.
+Verifique se você tem um tipo de projeto executável e se '{0}' dá suporte a esse projeto.
+Um projeto executável deve ter como destino um TFM executável (por exemplo, o net5.0) e ter o OutputType 'Exe'.
+O {1} atual é '{2}'.{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Ele tem diversas estruturas como destino. Especifique que estrutura executar usando '{0}'.
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Mover para cima e para baixo para ver mais estruturas
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Ele tem diversas estruturas como destino. Especifique que estrutura executar usa
Type to search
- Digite para pesquisar
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Selecione a estrutura de destino para executar:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
index 8f144b09ea22..4d108ae99863 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
@@ -57,6 +57,21 @@
АвторыTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Сборка проекта .NET.
@@ -902,7 +917,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- Рабочие нагрузки не установлены, не нужно ничего восстанавливать. Запустите "Поиск рабочей нагрузки DotNet", чтобы найти рабочие нагрузки для установки.
+ Рабочие нагрузки не установлены, не нужно ничего восстанавливать. Запустите "Поиск рабочей нагрузки DotNet", чтобы найти рабочие нагрузки для установки.
@@ -1219,7 +1234,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Укажите выходной каталог (нажмите клавишу ВВОД для значения по умолчанию: "{0}", каталог не должен существовать):
+ Укажите выходной каталог ({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Откат установки пакета {0}...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Доступные целевые платформы:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Сборка…
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.Не удалось запустить цель {0} для обнаружения команд выполнения для этого проекта. Исправьте ошибки и предупреждения и повторите попытку.
@@ -1344,7 +1369,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Example
- Пример
+ Example
@@ -1381,12 +1406,17 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- Не удается продолжить работу с проектом "{0}".
-Убедитесь, что тип проекта поддерживает запуск.
-Чтобы поддерживать запуск, проект должен быть предназначен для TFM с поддержкой запуска (например, net{1}) и иметь тип выдаваемого результата (OutputType) "Exe".
-Сейчас тип результата(OutputType) — "{2}".
+ Не удалось запустить проект.
+Убедитесь, что тип проекта поддерживает запуск и что "{0}" поддерживает этот проект.
+Запускаемый проект должен быть предназначен для TFM с поддержкой запуска (например, net5.0) и иметь тип выходных данных "EXE".
+Текущий {1} — "{2}".{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Проект предназначен для нескольких платформ. Укажите платформу, для которой следует запустить проект, с помощью "{0}".
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Прокрутите вверх и вниз, чтобы увидеть больше платформ
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Your project targets multiple frameworks. Specify which framework to run using '
Type to search
- Введите текст для поиска
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Выберите целевую платформу для запуска:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
index be4570e5cc19..5ec84a882619 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
@@ -57,6 +57,21 @@
YazarlarTable lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.Bir .NET projesi derler.
@@ -902,7 +917,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- İş yükü yüklenmediğinden onarılacak iş yükü yok. Yüklenecek iş yüklerini bulmak için `dotnet workload search` çalıştırın.
+ İş yükü yüklenmediğinden onarılacak iş yükü yok. Yüklenecek iş yüklerini bulmak için `dotnet workload search` çalıştırın.
@@ -1219,7 +1234,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- Çıkış dizinini belirtin (varsayılan için Enter tuşuna basın: '{0}', dizin mevcut olmamalıdır):
+ Çıkış dizinini belirtin ({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
{0} paketi için yükleme geri alınıyor...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- Mevcut hedef çerçeveler:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Derleniyor...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.Çalıştırma komutlarını bulmak için {0} hedefini çalıştırma bu proje için başarısız oldu. Hataları ve uyarıları düzeltip yeniden çalıştırın.
@@ -1344,7 +1369,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Example
- Örnek
+ Example
@@ -1381,12 +1406,17 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- '{0}' projesine devam edilemiyor.
-Çalıştırılabilir bir proje türüne sahip olduğunuzdan emin olun.
-Çalıştırılabilir bir proje, çalıştırılabilir bir TFM'yi (örneğin, net{1}) hedeflemeli ve OutputType ‘Exe’ değerine sahip olmalıdır.
-Geçerli OutputType '{2}'.
+ Projeniz çalıştırılamıyor.
+Çalıştırılabilir bir proje türüne sahip olduğunuzdan ve bu projenin '{0}' tarafından desteklendiğinden emin olun.
+Çalıştırılabilir proje, çalıştırılabilir bir TFM’yi (örneğin, net5.0) hedeflemeli ve OutputType değeri 'Exe' olmalıdır.
+Geçerli {1}: '{2}'.{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
Projeniz birden fazla Framework'ü hedefliyor. '{0}' kullanarak hangi Framework'ün çalıştırılacağını belirtin.
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- Yukarı ve aşağı hareket ederek daha fazla çerçeve görüntüleyin
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Projeniz birden fazla Framework'ü hedefliyor. '{0}' kullanarak hangi Framework'
Type to search
- Aramak için yazın
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- Çalıştırmak için hedef çerçeveyi seçin:
+ Select the target framework to run:
@@ -1816,9 +1861,9 @@ and the corresponding package Ids for installed tools using the command
'dotnet tool list'.
'{0}' paket kimliğine sahip araç bulunamadı.
-Araçlar, aracı çağırırken kullandığınız araç adından farklı olabilen
-paket kimlikleri kullanılarak kaldırılır. Yüklü araçların araç adlarını ve
-karşılık gelen paket kimliklerini bulmak için
+Araçlar, aracı çağırırken kullandığınız araç adından farklı olabilen
+paket kimlikleri kullanılarak kaldırılır. Yüklü araçların araç adlarını ve
+karşılık gelen paket kimliklerini bulmak için
'dotnet tool list' komutunu kullanabilirsiniz.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
index 04d30caaa767..f1756cdf26a6 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
@@ -57,6 +57,21 @@
作者Table lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.生成 .NET 项目。
@@ -902,7 +917,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- 未安装工作负载,没有要修复的内容。请运行“dotnet 工作负载搜索”,查找要安装的工作负载。
+ 未安装工作负载,没有要修复的内容。请运行“dotnet workload search”,查找要安装的工作负载。
@@ -1219,7 +1234,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- 指定输出目录(按 Enter 使用默认值: ‘{0}’,目录不得存在):
+ 指定输出目录({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
正在回滚包 {0} 的安装...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- 可用的目标框架:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
正在生成...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.为此项目运行 {0} 目标以发现运行命令失败。请修复错误和警告,然后再次运行。
@@ -1344,7 +1369,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Example
- 示例
+ Example
@@ -1381,12 +1406,17 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- 无法继续进行项目 ‘{0}’。
-确保具有可运行的项目类型。
-可运行的项目应面向可运行的 TFM (例如 net{1})且其 OutputType 为 ‘Exe’。
-当前 OutputType 为 ‘{2}’。
+ 无法运行项目。
+请确保你具有可运行的项目类型且“{0}”支持此项目。
+可运行的项目应面向可运行的 TFM (例如 net5.0)且其 OutputType 为 "Exe"。
+当前的 {1} 为“{2}”。{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
你的项目面向多个框架。请指定要使用“{0}”运行的框架。
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- 上移或下移以显示更多框架
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Your project targets multiple frameworks. Specify which framework to run using '
Type to search
- 键入以搜索
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- 选择要运行的目标框架:
+ Select the target framework to run:
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
index bb8d0a9ca790..e739b31721f7 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
@@ -57,6 +57,21 @@
作者Table lable
+
+ The device identifier to use for running the application.
+ The device identifier to use for running the application.
+
+
+
+ DEVICE
+ DEVICE
+
+
+
+ List available devices for running the application.
+ List available devices for running the application.
+
+ Build a .NET project.建置 .NET 專案。
@@ -428,7 +443,7 @@ See https://aka.ms/dotnet-test/mtp for more information.
The following exception occurred when running the test module with RunCommand '{0}' and RunArguments '{1}':
{2}
- 使用 RunCommand '{0}' 和 RunArguments '{1}' 執行測試模組時,發生以下例外狀況:
+ 使用 RunCommand '{0}' 和 RunArguments '{1}' 執行測試模組時,發生以下例外狀況:
{2}{Locked="RunCommand"}{Locked="RunArguments"}
@@ -902,7 +917,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
No workloads are installed, nothing to repair. Run `dotnet workload search` to find workloads to install.
- 未安裝任何工作負載,沒有要修復的項目。請執行 `dotnet workload search` 以尋找要安裝的工作負載。
+ 未安裝任何工作負載,沒有要修復的項目。請執行 `dotnet workload search` 以尋找要安裝的工作負載。
@@ -1219,7 +1234,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Specify the output directory (press Enter for default: '{0}', directory must not exist):
- 請指定輸出目錄 (按 Enter 鍵以使用預設值: '{0}',目錄必須不存在):
+ 指定輸出目錄 ({0}):{0} is the default value
@@ -1327,9 +1342,14 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
正在回復套件 {0} 安裝...
+
+ Available devices:
+ Available devices:
+
+ Available target frameworks:
- 可用的目標架構:
+ Available target frameworks:
@@ -1337,6 +1357,11 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
正在建置...
+
+ Deployment to device failed. Fix any deployment errors and run again.
+ Deployment to device failed. Fix any deployment errors and run again.
+
+ Running the {0} target to discover run commands failed for this project. Fix the errors and warnings and run again.執行 {0} 目標以探索對此專案的執行命令失敗。修正錯誤和警告,然後重新執行。
@@ -1344,7 +1369,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Example
- 範例
+ Example
@@ -1362,7 +1387,7 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Cannot use launch profile '{0}' because the launch settings file could not be located. Locations tried:
{1}
- 無法使用啟動設定檔 '{0}',因為找不到啟動設定檔檔案。嘗試的位置:
+ 無法使用啟動設定檔 '{0}',因為找不到啟動設定檔檔案。嘗試的位置:
{1}
@@ -1381,12 +1406,17 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net{1}) and have OutputType 'Exe'.
The current OutputType is '{2}'.
- 無法繼續處理專案 '{0}'。
-請確定您有可執行的專案類型。
-可執行的專案應以可執行的 TFM (例如 net{1}) 為目標,且 OutputType 應為 'Exe'。
-目前的 OutputType 為 '{2}'。
+ 無法執行您的專案。
+請確定您有可執行的專案類型,並確定 '{0}' 支援此專案。
+可執行的專案應以可執行的 TFM (例如 net5.0) 為目標,且 OutputType 應為 'Exe'。
+目前的 {1} 為 '{2}'。{0} is project file path. {1} is dotnet framework version. {2} is the project output type.{Locked="OutputType"}{Locked="Exe"}
+
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+ Unable to run this project because multiple devices are available. Please specify which device to use by passing the {0} argument with one of the following values:
+
+ Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '{0}'.
@@ -1394,9 +1424,19 @@ Your project targets multiple frameworks. Specify which framework to run using '
您的專案以多重架構為目標。請使用 '{0}' 指定要執行的架構。
+
+ Move up and down to reveal more devices
+ Move up and down to reveal more devices
+
+ Move up and down to reveal more frameworks
- 上下移動以顯示更多的架構
+ Move up and down to reveal more frameworks
+
+
+
+ No devices are available for this project.
+ No devices are available for this project.
@@ -1406,12 +1446,17 @@ Your project targets multiple frameworks. Specify which framework to run using '
Type to search
- 要搜尋的類型
+ Type to search
+
+
+
+ Select a device to run on:
+ Select a device to run on:Select the target framework to run:
- 選取要執行的目標架構:
+ Select the target framework to run:
diff --git a/test/TestAssets/TestProjects/DotnetRunDevices/DotnetRunDevices.csproj b/test/TestAssets/TestProjects/DotnetRunDevices/DotnetRunDevices.csproj
new file mode 100644
index 000000000000..04ce32c6db1d
--- /dev/null
+++ b/test/TestAssets/TestProjects/DotnetRunDevices/DotnetRunDevices.csproj
@@ -0,0 +1,57 @@
+
+
+
+ Exe
+ net9.0;$(CurrentTargetFramework)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(IntermediateOutputPath)DeviceInfo.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/TestAssets/TestProjects/DotnetRunDevices/Program.cs b/test/TestAssets/TestProjects/DotnetRunDevices/Program.cs
new file mode 100644
index 000000000000..5d9e6d61d1e7
--- /dev/null
+++ b/test/TestAssets/TestProjects/DotnetRunDevices/Program.cs
@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+namespace DotNetRunDevices
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Hello from multi-targeted app!");
+ Console.WriteLine($"Target Framework: {AppContext.TargetFrameworkName}");
+ Console.WriteLine($"Runtime: {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}");
+
+ // DeviceInfo class is generated at build time when Device property is set
+ Console.WriteLine($"Device: {DeviceInfo.Device}");
+ Console.WriteLine($"RuntimeIdentifier: {DeviceInfo.RuntimeIdentifier}");
+ }
+ }
+}
diff --git a/test/dotnet.Tests/CommandTests/Run/GivenDotnetRunSelectsDevice.cs b/test/dotnet.Tests/CommandTests/Run/GivenDotnetRunSelectsDevice.cs
new file mode 100644
index 000000000000..c2c1948b12a5
--- /dev/null
+++ b/test/dotnet.Tests/CommandTests/Run/GivenDotnetRunSelectsDevice.cs
@@ -0,0 +1,379 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Build.Logging.StructuredLogger;
+using Microsoft.DotNet.Cli.Commands;
+using StructuredLoggerTarget = Microsoft.Build.Logging.StructuredLogger.Target;
+
+namespace Microsoft.DotNet.Cli.Run.Tests;
+
+///
+/// Integration tests for device selection in dotnet run
+///
+public class GivenDotnetRunSelectsDevice : SdkTest
+{
+ public GivenDotnetRunSelectsDevice(ITestOutputHelper log) : base(log)
+ {
+ }
+
+ ///
+ /// Helper method to assert conditions about MSBuild target execution in a binlog file
+ ///
+ private static void AssertTargetInBinlog(string binlogPath, string targetName, Action> assertion)
+ {
+ var build = BinaryLog.ReadBuild(binlogPath);
+ var targets = build.FindChildrenRecursive(
+ target => target.Name == targetName);
+
+ assertion(targets);
+ }
+
+ [Fact]
+ public void ItFailsInNonInteractiveMode_WhenMultipleDevicesAvailableAndNoneSpecified()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .WithEnvironmentVariable("DOTNET_CLI_UI_LANGUAGE", "en-US")
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--no-interactive");
+
+ result.Should().Fail()
+ .And.HaveStdErrContaining(string.Format(CliCommandStrings.RunCommandExceptionUnableToRunSpecifyDevice, "--device"));
+ }
+
+ [Fact]
+ public void ItListsDevicesForSpecifiedFramework()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--list-devices");
+
+ result.Should().Pass()
+ .And.HaveStdOutContaining("test-device-1")
+ .And.HaveStdOutContaining("test-device-2")
+ .And.HaveStdOutContaining("Emulator");
+ }
+
+ [Theory]
+ [InlineData("test-device-1")]
+ [InlineData("test-device-2")]
+ public void ItRunsDifferentDevicesInMultiTargetedApp(string deviceId)
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--device", deviceId)
+ .Should().Pass()
+ .And.HaveStdOutContaining($"Device: {deviceId}");
+ }
+
+ [Fact]
+ public void ItShowsErrorMessageWithAvailableDevices_InNonInteractiveMode()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .WithEnvironmentVariable("DOTNET_CLI_UI_LANGUAGE", "en-US")
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--no-interactive");
+
+ result.Should().Fail()
+ .And.HaveStdErrContaining(string.Format(CliCommandStrings.RunCommandExceptionUnableToRunSpecifyDevice, "--device"))
+ .And.HaveStdErrContaining("test-device-1")
+ .And.HaveStdErrContaining("test-device-2");
+ }
+
+ [Fact]
+ public void ItDoesNotPromptForDeviceWhenComputeAvailableDevicesTargetDoesNotExist()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset(
+ "NETFrameworkReferenceNETStandard20",
+ testAssetSubdirectory: TestAssetSubdirectories.DesktopTestProjects)
+ .WithSource();
+
+ string projectDirectory = Path.Combine(testInstance.Path, "MultiTFMTestApp");
+
+ // This project doesn't have ComputeAvailableDevices target, so it should just run
+ new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(projectDirectory)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework)
+ .Should().Pass()
+ .And.HaveStdOutContaining("This string came from the test library!");
+ }
+
+ [Fact]
+ public void ItTreatsEmptyDeviceSpecificationAsNotSpecified()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .WithEnvironmentVariable("DOTNET_CLI_UI_LANGUAGE", "en-US")
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "-p:Device=", "--no-interactive");
+
+ result.Should().Fail()
+ .And.HaveStdErrContaining(string.Format(CliCommandStrings.RunCommandExceptionUnableToRunSpecifyDevice, "--device"));
+ }
+
+ [Fact]
+ public void ItWorksWithDevicePropertySyntax()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string deviceId = "test-device-1";
+ new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, $"-p:Device={deviceId}")
+ .Should().Pass()
+ .And.HaveStdOutContaining($"Device: {deviceId}");
+ }
+
+ [Fact]
+ public void ItWorksWithDeviceWithoutRuntimeIdentifier()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string deviceId = "test-device-2";
+ new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--device", deviceId)
+ .Should().Pass()
+ .And.HaveStdOutContaining($"Device: {deviceId}")
+ .And.HaveStdOutContaining("RuntimeIdentifier:");
+ }
+
+ [Theory]
+ [InlineData(true)] // interactive
+ [InlineData(false)] // non-interactive
+ public void ItAutoSelectsSingleDeviceWithoutPrompting(bool interactive)
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string binlogPath = Path.Combine(testInstance.Path, "msbuild-dotnet-run.binlog");
+
+ var command = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path);
+
+ var args = new List { "--framework", ToolsetInfo.CurrentTargetFramework, "-p:SingleDevice=true", "-bl" };
+ if (!interactive)
+ {
+ args.Add("--no-interactive");
+ }
+
+ var result = command.Execute(args.ToArray());
+
+ // Should auto-select the single device and run successfully
+ result.Should().Pass()
+ .And.HaveStdOutContaining("Device: single-device")
+ .And.HaveStdOutContaining($"RuntimeIdentifier: {RuntimeInformation.RuntimeIdentifier}");
+
+ // Verify the binlog file was created and the ComputeAvailableDevices target ran
+ File.Exists(binlogPath).Should().BeTrue("the binlog file should be created");
+ AssertTargetInBinlog(binlogPath, "ComputeAvailableDevices",
+ targets => targets.Should().NotBeEmpty("ComputeAvailableDevices target should run to discover available devices"));
+ }
+
+ [Fact]
+ public void ItCreatesBinlogWhenRequestedForDeviceSelection()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ // When /bl:device-list.binlog is specified, the verb "dotnet-run" is appended
+ string binlogPath = Path.Combine(testInstance.Path, "device-list-dotnet-run.binlog");
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--list-devices", "/bl:device-list.binlog");
+
+ result.Should().Pass()
+ .And.HaveStdOutContaining("test-device-1");
+
+ // Verify the binlog file was created with the unified logger and the ComputeAvailableDevices target ran
+ File.Exists(binlogPath).Should().BeTrue("the binlog file should be created when /bl: argument is provided");
+ AssertTargetInBinlog(binlogPath, "ComputeAvailableDevices",
+ targets => targets.Should().NotBeEmpty("ComputeAvailableDevices target should have been executed"));
+ }
+
+ [Fact]
+ public void ItFailsWhenNoDevicesAreAvailable()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .WithEnvironmentVariable("DOTNET_CLI_UI_LANGUAGE", "en-US")
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "-p:NoDevices=true", "--no-interactive");
+
+ result.Should().Fail()
+ .And.HaveStdErrContaining(CliCommandStrings.RunCommandNoDevicesAvailable);
+ }
+
+ [Theory]
+ [InlineData("--device")]
+ [InlineData("-p:Device=")]
+ public void ItDoesNotRunComputeAvailableDevicesWhenDeviceIsPreSpecified(string deviceArgPrefix)
+ {
+ string deviceId = "test-device-2";
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string binlogPath = Path.Combine(testInstance.Path, "msbuild-dotnet-run.binlog");
+
+ var args = new List { "--framework", ToolsetInfo.CurrentTargetFramework };
+ if (deviceArgPrefix == "--device")
+ {
+ args.Add("--device");
+ args.Add(deviceId);
+ }
+ else
+ {
+ args.Add($"{deviceArgPrefix}{deviceId}");
+ }
+ args.Add("-bl");
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute(args.ToArray());
+
+ // Should run successfully
+ result.Should().Pass()
+ .And.HaveStdOutContaining($"Device: {deviceId}");
+
+ // Verify the binlog file was created and the ComputeAvailableDevices target did not run
+ File.Exists(binlogPath).Should().BeTrue("the binlog file should be created");
+ AssertTargetInBinlog(binlogPath, "ComputeAvailableDevices",
+ targets => targets.Should().BeEmpty("ComputeAvailableDevices target should not have been executed when device is pre-specified"));
+ }
+
+ [Fact]
+ public void ItPromptsForTargetFrameworkEvenWhenDeviceIsSpecified()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string deviceId = "test-device-1";
+
+ // Don't specify --framework, only specify --device
+ // This should fail in non-interactive mode because framework selection is still needed
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .WithEnvironmentVariable("DOTNET_CLI_UI_LANGUAGE", "en-US")
+ .Execute("--device", deviceId, "--no-interactive");
+
+ // Should fail with framework selection error, not device selection error
+ result.Should().Fail()
+ .And.HaveStdErrContaining("Your project targets multiple frameworks. Specify which framework to run using '--framework'");
+ }
+
+ [Fact]
+ public void ItCallsDeployToDeviceTargetWhenDeviceIsSpecified()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string deviceId = "test-device-1";
+ string binlogPath = Path.Combine(testInstance.Path, "msbuild-dotnet-run.binlog");
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--device", deviceId, "-bl");
+
+ // Should run successfully
+ result.Should().Pass()
+ .And.HaveStdOutContaining($"Device: {deviceId}");
+
+ // Verify the binlog file was created and the DeployToDevice target ran
+ File.Exists(binlogPath).Should().BeTrue("the binlog file should be created");
+ AssertTargetInBinlog(binlogPath, "DeployToDevice",
+ targets => targets.Should().NotBeEmpty("DeployToDevice target should have been executed"));
+ }
+
+ [Fact]
+ public void ItCallsDeployToDeviceTargetEvenWithNoBuild()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string deviceId = "test-device-1";
+ string binlogPath = Path.Combine(testInstance.Path, "msbuild-dotnet-run.binlog");
+
+ // First build the project with the device so DeviceInfo gets generated
+ // Note: dotnet build doesn't support --device flag, use -p:Device= instead
+ new DotnetCommand(Log, "build")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, $"-p:Device={deviceId}")
+ .Should().Pass();
+
+ // Now run with --no-build
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--device", deviceId, "--no-build", "-bl");
+
+ // Should run successfully
+ result.Should().Pass()
+ .And.HaveStdOutContaining($"Device: {deviceId}");
+
+ // Verify the binlog file was created and the DeployToDevice target ran
+ File.Exists(binlogPath).Should().BeTrue("the binlog file should be created");
+ AssertTargetInBinlog(binlogPath, "DeployToDevice",
+ targets => targets.Should().NotBeEmpty("DeployToDevice target should have been executed even with --no-build"));
+ }
+
+ [Fact]
+ public void ItCallsDeployToDeviceTargetWhenDeviceIsAutoSelected()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string binlogPath = Path.Combine(testInstance.Path, "msbuild-dotnet-run.binlog");
+
+ // Run with auto-selection of single device
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "-p:SingleDevice=true", "-bl");
+
+ // Should run successfully
+ result.Should().Pass()
+ .And.HaveStdOutContaining("Device: single-device");
+
+ // Verify the binlog file was created
+ File.Exists(binlogPath).Should().BeTrue("the binlog file should be created");
+
+ // DeployToDevice target should have been called since a device was selected
+ AssertTargetInBinlog(binlogPath, "DeployToDevice",
+ targets => targets.Should().NotBeEmpty("DeployToDevice target should have been executed when a device is selected"));
+ }
+
+ [Fact]
+ public void ItPassesRuntimeIdentifierToDeployToDeviceTarget()
+ {
+ var testInstance = _testAssetsManager.CopyTestAsset("DotnetRunDevices")
+ .WithSource();
+
+ string deviceId = "test-device-1";
+ string rid = RuntimeInformation.RuntimeIdentifier;
+
+ var result = new DotnetCommand(Log, "run")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute("--framework", ToolsetInfo.CurrentTargetFramework, "--device", deviceId, "--runtime", rid);
+
+ // Should run successfully and show the RuntimeIdentifier in the app output
+ result.Should().Pass()
+ .And.HaveStdOutContaining($"Device: {deviceId}")
+ .And.HaveStdOutContaining($"RuntimeIdentifier: {rid}");
+ }
+}
diff --git a/test/dotnet.Tests/CommandTests/Run/RunCommandTests.cs b/test/dotnet.Tests/CommandTests/Run/RunCommandTests.cs
index 5504bd51c710..37a947eb8f2b 100644
--- a/test/dotnet.Tests/CommandTests/Run/RunCommandTests.cs
+++ b/test/dotnet.Tests/CommandTests/Run/RunCommandTests.cs
@@ -23,11 +23,13 @@ private static RunCommand CreateRunCommand(
entryPointFileFullPath: null,
launchProfile: null,
noLaunchProfile: false,
- noLaunchProfileArguments,
+ noLaunchProfileArguments: noLaunchProfileArguments,
+ device: null,
+ listDevices: false,
noRestore: false,
noCache: false,
interactive: false,
- MSBuildArgs.FromOtherArgs([]),
+ msbuildArgs: MSBuildArgs.FromOtherArgs([]),
applicationArgs: applicationArgs ?? [],
readCodeFromStdin: false,
environmentVariables: new Dictionary());
@@ -86,7 +88,7 @@ public void Executable_DefaultWorkingDirectory()
};
var runCommand = CreateRunCommand(projectPath);
- var command = (Command)runCommand.GetTargetCommand(model, projectFactory: null, cachedRunProperties: null);
+ var command = (Command)runCommand.GetTargetCommand(model, projectFactory: null, cachedRunProperties: null, logger: null);
Assert.Equal("executable", command.StartInfo.FileName);
Assert.Equal(dir, command.StartInfo.WorkingDirectory);
@@ -111,7 +113,7 @@ public void Executable_NoLaunchProfileArguments()
};
var runCommand = CreateRunCommand(projectPath, noLaunchProfileArguments: true);
- var command = (Command)runCommand.GetTargetCommand(model, projectFactory: null, cachedRunProperties: null);
+ var command = (Command)runCommand.GetTargetCommand(model, projectFactory: null, cachedRunProperties: null, logger: null);
Assert.Equal("", command.StartInfo.Arguments);
}
@@ -134,7 +136,7 @@ public void Executable_ApplicationArguments()
};
var runCommand = CreateRunCommand(projectPath, applicationArgs: ["app 1", "app 2"]);
- var command = (Command)runCommand.GetTargetCommand(model, projectFactory: null, cachedRunProperties: null);
+ var command = (Command)runCommand.GetTargetCommand(model, projectFactory: null, cachedRunProperties: null, logger: null);
Assert.Equal("\"app 1\" \"app 2\"", command.StartInfo.Arguments);
}
diff --git a/test/dotnet.Tests/CompletionTests/snapshots/bash/DotnetCliSnapshotTests.VerifyCompletions.verified.sh b/test/dotnet.Tests/CompletionTests/snapshots/bash/DotnetCliSnapshotTests.VerifyCompletions.verified.sh
index 880ac16e77a9..bf969a10f194 100644
--- a/test/dotnet.Tests/CompletionTests/snapshots/bash/DotnetCliSnapshotTests.VerifyCompletions.verified.sh
+++ b/test/dotnet.Tests/CompletionTests/snapshots/bash/DotnetCliSnapshotTests.VerifyCompletions.verified.sh
@@ -1379,7 +1379,7 @@ _testhost_run() {
prev="${COMP_WORDS[COMP_CWORD-1]}"
COMPREPLY=()
- opts="--configuration --framework --project --file --launch-profile --no-launch-profile --no-build --interactive --no-restore --no-cache --self-contained --no-self-contained --verbosity --runtime --arch --os --disable-build-servers --artifacts-path --environment --help"
+ opts="--configuration --framework --project --file --launch-profile --no-launch-profile --device --list-devices --no-build --interactive --no-restore --no-cache --self-contained --no-self-contained --verbosity --runtime --arch --os --disable-build-servers --artifacts-path --environment --help"
if [[ $COMP_CWORD == "$1" ]]; then
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
diff --git a/test/dotnet.Tests/CompletionTests/snapshots/pwsh/DotnetCliSnapshotTests.VerifyCompletions.verified.ps1 b/test/dotnet.Tests/CompletionTests/snapshots/pwsh/DotnetCliSnapshotTests.VerifyCompletions.verified.ps1
index e0f1ecad057d..8dc3c5f9aec1 100644
--- a/test/dotnet.Tests/CompletionTests/snapshots/pwsh/DotnetCliSnapshotTests.VerifyCompletions.verified.ps1
+++ b/test/dotnet.Tests/CompletionTests/snapshots/pwsh/DotnetCliSnapshotTests.VerifyCompletions.verified.ps1
@@ -849,6 +849,8 @@ Register-ArgumentCompleter -Native -CommandName 'testhost' -ScriptBlock {
[CompletionResult]::new('--launch-profile', '--launch-profile', [CompletionResultType]::ParameterName, "The name of the launch profile (if any) to use when launching the application.")
[CompletionResult]::new('--launch-profile', '-lp', [CompletionResultType]::ParameterName, "The name of the launch profile (if any) to use when launching the application.")
[CompletionResult]::new('--no-launch-profile', '--no-launch-profile', [CompletionResultType]::ParameterName, "Do not attempt to use launchSettings.json or [app].run.json to configure the application.")
+ [CompletionResult]::new('--device', '--device', [CompletionResultType]::ParameterName, "The device identifier to use for running the application.")
+ [CompletionResult]::new('--list-devices', '--list-devices', [CompletionResultType]::ParameterName, "List available devices for running the application.")
[CompletionResult]::new('--no-build', '--no-build', [CompletionResultType]::ParameterName, "Do not build the project before running. Implies --no-restore.")
[CompletionResult]::new('--interactive', '--interactive', [CompletionResultType]::ParameterName, "Allows the command to stop and wait for user input or action (for example to complete authentication).")
[CompletionResult]::new('--no-restore', '--no-restore', [CompletionResultType]::ParameterName, "Do not restore the project before building.")
diff --git a/test/dotnet.Tests/CompletionTests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh b/test/dotnet.Tests/CompletionTests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh
index a9ec3e4ad8a1..aae722f223fa 100644
--- a/test/dotnet.Tests/CompletionTests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh
+++ b/test/dotnet.Tests/CompletionTests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh
@@ -893,6 +893,8 @@ _testhost() {
'--launch-profile=[The name of the launch profile (if any) to use when launching the application.]:LAUNCH_PROFILE: ' \
'-lp=[The name of the launch profile (if any) to use when launching the application.]:LAUNCH_PROFILE: ' \
'--no-launch-profile[Do not attempt to use launchSettings.json or \[app\].run.json to configure the application.]' \
+ '--device=[The device identifier to use for running the application.]:DEVICE: ' \
+ '--list-devices[List available devices for running the application.]' \
'--no-build[Do not build the project before running. Implies --no-restore.]' \
'--interactive=[Allows the command to stop and wait for user input or action (for example to complete authentication).]: :((False\:"False" True\:"True" ))' \
'--no-restore[Do not restore the project before building.]' \
diff --git a/test/dotnet.Tests/dotnet.Tests.csproj b/test/dotnet.Tests/dotnet.Tests.csproj
index d5c8e9a22b22..0cff111bd10f 100644
--- a/test/dotnet.Tests/dotnet.Tests.csproj
+++ b/test/dotnet.Tests/dotnet.Tests.csproj
@@ -79,6 +79,7 @@
+