Fix blazor-gateway.dll not found: pack BlazorGateway subfolder into wasm packages#130764
Draft
pavelsavara with Copilot wants to merge 5 commits into
Draft
Fix blazor-gateway.dll not found: pack BlazorGateway subfolder into wasm packages#130764pavelsavara with Copilot wants to merge 5 commits into
pavelsavara with Copilot wants to merge 5 commits into
Conversation
Co-authored-by: pavelsavara <[email protected]>
Co-authored-by: pavelsavara <[email protected]>
Co-authored-by: pavelsavara <[email protected]>
Copilot created this pull request from a session on behalf of
pavelsavara
July 15, 2026 10:03
View session
|
Azure Pipelines: Successfully started running 4 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Member
|
Does the subprocess approach work with HotReload? |
Co-authored-by: pavelsavara <[email protected]>
Copilot
AI
changed the title
Unify WasmAppHost dev server with Blazor Gateway
Fix blazor-gateway.dll not found: pack BlazorGateway subfolder into wasm packages
Jul 15, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the browser WASM toolchain to ship and launch the Blazor Gateway (blazor-gateway.dll) correctly by (1) copying the Gateway payload next to WasmAppHost under a BlazorGateway/ subfolder and (2) ensuring the WASM SDK NuGet packages pack that subfolder recursively so runtime lookup succeeds.
Changes:
- Copy
Microsoft.AspNetCore.Components.Gatewaypayload into the WasmAppHost output underBlazorGateway/. - Replace the in-proc dev server implementation with a subprocess-based
GatewayServerthat locates and launchesblazor-gateway.dll. - Pack the
WasmAppHost/BlazorGateway/subtree recursively into the three WASM SDK packages; also enable SPA fallback default for root apps.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/mono/wasm/host/WasmAppHost.csproj | Adds Gateway package reference + copies/packs its tools/** payload next to WasmAppHost. |
| src/mono/wasm/host/README.md | Documents Gateway-based dev server behavior and known feature gaps vs legacy server. |
| src/mono/wasm/host/DevServer/WebAssemblyNetDebugProxyAppBuilderExtensions.cs | Removes legacy debugging middleware implementation. |
| src/mono/wasm/host/DevServer/GatewayServer.cs | Adds subprocess launcher that parses Gateway stdout to determine listening URLs. |
| src/mono/wasm/host/DevServer/DevServerStartup.cs | Removes legacy in-process dev server startup pipeline. |
| src/mono/wasm/host/DevServer/DevServer.cs | Removes legacy dev server host builder entrypoint. |
| src/mono/wasm/host/DevServer/DebugProxyLauncher.cs | Removes legacy debug proxy launcher implementation. |
| src/mono/wasm/host/DevServer/ContentEncodingNegotiator.cs | Removes legacy content-encoding negotiation middleware. |
| src/mono/wasm/host/BrowserHost.cs | Routes static web assets scenario to the new GatewayServer and warns about missing console forwarding. |
| src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/Microsoft.NET.Sdk.WebAssembly.Pack.pkgproj | Packs WasmAppHost/BlazorGateway/** recursively into the package. |
| src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props | Sets StaticWebAssetSpaFallbackEnabled=true by default for root apps. |
| src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk/Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk.pkgproj | Packs WasmAppHost/BlazorGateway/** recursively into the package. |
| src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj | Packs WasmAppHost/BlazorGateway/** recursively into the package. |
| eng/Versions.props | Adds a pinned Gateway package version property consumed by WasmAppHost. |
Comment on lines
+22
to
+24
| <_blazorGatewayFiles Include="$(PkgMicrosoft_AspNetCore_Components_Gateway)\tools\**\*" /> | ||
| <None Include="@(_blazorGatewayFiles)" CopyToOutputDirectory="PreserveNewest" Link="BlazorGateway\%(RecursiveDir)%(Filename)%(Extension)" /> | ||
| <PackageFile Include="@(_blazorGatewayFiles)" TargetPath="tools\$(NetCoreAppCurrent)\BlazorGateway\%(RecursiveDir)" /> |
Comment on lines
+47
to
+50
| await host.StartAsync(token); | ||
|
|
||
| ServerURLs serverUrls = await realUrlsAvailableTcs.Task; | ||
| return (serverUrls, host); |
Comment on lines
+189
to
+232
| Match listeningMatch = NowListeningRegex.Match(line); | ||
| if (listeningMatch.Success) | ||
| { | ||
| lock (_listeningUrls) | ||
| { | ||
| _listeningUrls.Add(listeningMatch.Groups["url"].Value.Trim()); | ||
| } | ||
| } | ||
| else if (ApplicationStartedRegex.IsMatch(line)) | ||
| { | ||
| ResolveServerUrls(); | ||
| } | ||
|
|
||
| // Suppress the gateway's own status messages so they are not confused with the application's output. | ||
| foreach (string prefix in MessageSuppressionPrefixes) | ||
| { | ||
| if (line.StartsWith(prefix, StringComparison.Ordinal)) | ||
| return; | ||
| } | ||
|
|
||
| Console.WriteLine(line); | ||
| } | ||
|
|
||
| private void OnErrorDataReceived(object sender, DataReceivedEventArgs eventArgs) | ||
| { | ||
| if (!string.IsNullOrEmpty(eventArgs.Data)) | ||
| _logger.LogError("[BlazorGateway] {Message}", eventArgs.Data); | ||
| } | ||
|
|
||
| private void ResolveServerUrls() | ||
| { | ||
| string? http; | ||
| string? https; | ||
| lock (_listeningUrls) | ||
| { | ||
| http = GetServerAddress(_listeningUrls, secure: false); | ||
| https = GetServerAddress(_listeningUrls, secure: true); | ||
| } | ||
|
|
||
| if (http is null) | ||
| _realUrlsAvailableTcs.TrySetException(new InvalidOperationException("Failed to determine the Blazor Gateway's HTTP address or port.")); | ||
| else | ||
| _realUrlsAvailableTcs.TrySetResult(new ServerURLs(http, https)); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The WasmAppHost browser dev server launches the Blazor Gateway from a
BlazorGateway/subfolder next toWasmAppHost.dll, but the wasm packaging projects collected WasmAppHost output with a non-recursive glob ($(WasmAppHostDir)\*). The subfolder — andblazor-gateway.dll— was omitted from the shipped packages, soGatewayServer.LocateGatewayDll()threwFileNotFoundExceptionat runtime (observed in Wasm.Build.Tests).Changes
BlazorGatewaysubtree recursively in the three pkgprojs that ship WasmAppHost (Microsoft.NET.Sdk.WebAssembly.Pack,Microsoft.NET.Runtime.WebAssembly.Sdk,Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk), preserving the folder structure so the payload lands atWasmAppHost/BlazorGateway/.%(RecursiveDir)transform — the subtree is globbed into a raw item first, then re-included withTargetPath, because%(RecursiveDir)is not populated when referenced on the same wildcardInclude(would otherwise flatten nested files).The Arcade packer treats the extension-less
TargetPathas a directory and appends the filename, producingWasmAppHost/BlazorGateway/blazor-gateway.dll— the exact path the loader searches.