| File: Process\WebServerProcessStateObserver.cs | Web Access |
| Project: src\sdk\src\Dotnet.Watch\Watch\Microsoft.DotNet.HotReload.Watch.csproj (Microsoft.DotNet.HotReload.Watch) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text.RegularExpressions; using Microsoft.Build.Graph; namespace Microsoft.DotNet.Watch; /// <summary> /// Observes the state of the web server by scanning its standard output for known patterns. /// Notifies when the server starts listening. /// </summary> internal static partial class WebServerProcessStateObserver { private static readonly Regex s_nowListeningRegex = GetNowListeningOnRegex(); private static readonly Regex s_aspireDashboardUrlRegex = GetAspireDashboardUrlRegex(); [GeneratedRegex(@"Now listening on: (?<url>.*)\s*$", RegexOptions.Compiled)] private static partial Regex GetNowListeningOnRegex(); [GeneratedRegex(@"Login to the dashboard at (?<url>.*)\s*$", RegexOptions.Compiled)] private static partial Regex GetAspireDashboardUrlRegex(); public static Action<OutputLine> GetObserver(ProjectGraphNode serverProject, Action<string> onServerListening) { // Workaround for Aspire dashboard launching: scan for "Login to the dashboard at " prefix in the output and use the URL. // TODO: https://github.com/dotnet/sdk/issues/9038 // Share launch profile processing logic as implemented in VS with dotnet-run and implement browser launching there. bool isAspireHost = serverProject.GetCapabilities().Contains(AspireServiceFactory.AppHostProjectCapability); var _notified = false; return line => { if (_notified) { return; } var match = (isAspireHost ? s_aspireDashboardUrlRegex : s_nowListeningRegex).Match(line.Content); if (!match.Success) { return; } _notified = true; onServerListening(match.Groups["url"].Value); }; } }