| File: BlazorDotNetCliRunner.cs | Web Access |
| Project: src\src\Aspire.Hosting.Blazor\Aspire.Hosting.Blazor.csproj (Aspire.Hosting.Blazor) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; using System.Text; using Aspire.Hosting.Dcp.Process; namespace Aspire.Hosting; /// <summary> /// Runs .NET CLI commands for Blazor projects. /// </summary> internal static class BlazorDotNetCliRunner { public static async Task<BlazorDotNetCliResult> RunAsync( string projectPath, string command, IReadOnlyList<string> arguments, bool machineReadableOutput, CancellationToken cancellationToken) { var executablePath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH") is { Length: > 0 } dotnetHostPath ? dotnetHostPath : "dotnet"; var argumentList = new List<string>(arguments.Count + 2) { command, projectPath }; argumentList.AddRange(arguments); var standardOutput = new StringBuilder(); var standardError = new StringBuilder(); var processSpec = new ProcessSpec(executablePath) { WorkingDirectory = Path.GetDirectoryName(projectPath)!, ArgumentList = argumentList, ThrowOnNonZeroReturnCode = false, OnOutputData = line => standardOutput.AppendLine(line), OnErrorData = line => standardError.AppendLine(line) }; if (machineReadableOutput) { // MSBuild queries emit JSON on stdout. Disable unrelated CLI messages that could // corrupt the machine-readable output before callers have a chance to parse it. processSpec.EnvironmentVariables["DOTNET_CLI_TELEMETRY_OPTOUT"] = "1"; processSpec.EnvironmentVariables["DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE"] = "1"; } Task<ProcessResult> pendingResult; IAsyncDisposable processDisposable; try { (pendingResult, processDisposable) = ProcessUtil.Run(processSpec); } catch (Exception ex) when (ex is InvalidOperationException or Win32Exception) { return new(executablePath, false, -1, "", "", ex); } await using (processDisposable.ConfigureAwait(false)) { var result = await pendingResult.WaitAsync(cancellationToken).ConfigureAwait(false); return new( executablePath, true, result.ExitCode, standardOutput.ToString(), standardError.ToString(), null); } } } internal readonly record struct BlazorDotNetCliResult( string Command, bool Started, int ExitCode, string StandardOutput, string StandardError, Exception? StartException);