You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When publishing an application with PublishAot=true, PublishSingleFile=true, or as self-contained, satellite resource assemblies (localized .resources.dll files in per-culture folders like cs/, de/, fr/, etc.) are not automatically excluded from the publish output directory. I believe these resources are already embedded in the single-file bundle or are unnecessary alongside a native AOT binary, yet they still appear as loose files in the output. This is confusing and made me think they were not correctly embedded.
Users must manually set <SatelliteResourceLanguages>en</SatelliteResourceLanguages> in their project file to suppress them. This property should not be required — the default behavior for PublishSingleFile and PublishAot scenarios should be to exclude satellite assembly folders from the publish output.
SatelliteResourceLanguages also does not seem to be properly excluding everything when I set the property - folders are still being generated when I set it to en in the dotnetup publish when I tried to set it locally.
Reproduction
Create a console app with <PublishAot>true</PublishAot> that references any NuGet package shipping satellite assemblies (e.g., System.CommandLine, Spectre.Console).
Run dotnet publish -r win-x64 -c Release.
Observe the publish output directory contains 13+ language subdirectories (cs/, de/, es/, fr/, it/, ja/, ko/, pl/, pt-BR/, ru/, tr/, zh-Hans/, zh-Hant/), each containing .resources.dll files that are unnecessary alongside the native binary.
Current behavior
PublishAot: The AOT compiler produces a native binary. Satellite .resources.dll files from the project and its NuGet dependencies are still copied to the publish directory as loose files in per-culture subdirectories. They serve no purpose — the native binary does not load them.
PublishSingleFile: Satellite assemblies are bundled into the single-file binary (they are not marked ExcludeFromSingleFile=true), yet their per-culture folders and .resources.dll files are also emitted as loose files in the publish output.
Self-contained: Same issue — satellite assemblies from runtime packs and NuGet packages are copied out even when they are not needed.
In all three cases, the only way I found to suppress the extra output is to manually set this variable, which does not seem to always work:
SatelliteResourceLanguages should not be required. The SDK should automatically suppress satellite assembly output for PublishAot and PublishSingleFile scenarios, since the resources are either embedded or unused.
The default for PublishSingleFile and PublishAot should behave as if SatelliteResourceLanguages is set to the project's neutral language (typically en), so that no extra per-culture folders are produced in the publish output.
Users who explicitly need satellite assemblies alongside the binary should be able to opt back in.
Impact
Disk space and artifact bloat
For a project like dotnetup (PublishAot=true) that references System.CommandLine, Microsoft.Deployment.DotNet.Releases, and Spectre.Console, the publish output contains 13 language directories × 3 .resources.dll files = 39 extra files and their parent directories. This bloats CI artifacts and wastes disk space, particularly in constrained environments like cross-build containers.
XML documentation files
A related concern: XML documentation files (.xml) from NuGet packages should also be excluded from publish output by default. These are developer-time assets, not runtime assets, and should not ship in a self-contained or AOT-published app.
Example CI artifacts showing the problem: official-dnup-ci build #2925196 — each per-RID dotnetup-executable-* artifact contains cs/, de/, es/, fr/, it/, ja/, ko/, pl/, pt-BR/, ru/, tr/, zh-Hans/, zh-Hant/ folders with satellite .resources.dll files that should not be present alongside the native AOT binary. Binlogs are also included in the build artifacts for investigation.
Summary
When publishing an application with
PublishAot=true,PublishSingleFile=true, or as self-contained, satellite resource assemblies (localized.resources.dllfiles in per-culture folders likecs/,de/,fr/, etc.) are not automatically excluded from the publish output directory. I believe these resources are already embedded in the single-file bundle or are unnecessary alongside a native AOT binary, yet they still appear as loose files in the output. This is confusing and made me think they were not correctly embedded.Users must manually set
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>in their project file to suppress them. This property should not be required — the default behavior forPublishSingleFileandPublishAotscenarios should be to exclude satellite assembly folders from the publish output.SatelliteResourceLanguagesalso does not seem to be properly excluding everything when I set the property - folders are still being generated when I set it toenin the dotnetup publish when I tried to set it locally.Reproduction
<PublishAot>true</PublishAot>that references any NuGet package shipping satellite assemblies (e.g.,System.CommandLine,Spectre.Console).dotnet publish -r win-x64 -c Release.cs/,de/,es/,fr/,it/,ja/,ko/,pl/,pt-BR/,ru/,tr/,zh-Hans/,zh-Hant/), each containing.resources.dllfiles that are unnecessary alongside the native binary.Current behavior
.resources.dllfiles from the project and its NuGet dependencies are still copied to the publish directory as loose files in per-culture subdirectories. They serve no purpose — the native binary does not load them.ExcludeFromSingleFile=true), yet their per-culture folders and.resources.dllfiles are also emitted as loose files in the publish output.In all three cases, the only way I found to suppress the extra output is to manually set this variable, which does not seem to always work:
Expected behavior
SatelliteResourceLanguagesshould not be required. The SDK should automatically suppress satellite assembly output for PublishAot and PublishSingleFile scenarios, since the resources are either embedded or unused.PublishSingleFileandPublishAotshould behave as ifSatelliteResourceLanguagesis set to the project's neutral language (typicallyen), so that no extra per-culture folders are produced in the publish output.Impact
Disk space and artifact bloat
For a project like
dotnetup(PublishAot=true) that referencesSystem.CommandLine,Microsoft.Deployment.DotNet.Releases, andSpectre.Console, the publish output contains 13 language directories × 3.resources.dllfiles = 39 extra files and their parent directories. This bloats CI artifacts and wastes disk space, particularly in constrained environments like cross-build containers.XML documentation files
A related concern: XML documentation files (
.xml) from NuGet packages should also be excluded from publish output by default. These are developer-time assets, not runtime assets, and should not ship in a self-contained or AOT-published app.Related
dotnetupexecutable publish output (Produce AOT, Runtime Specific, Cross Build Executables ofdotnetupsdk#53143), which currently ships 39 unnecessary satellite assembly files per RID alongside the native AOT binary.dotnetup-executable-*artifact containscs/,de/,es/,fr/,it/,ja/,ko/,pl/,pt-BR/,ru/,tr/,zh-Hans/,zh-Hant/folders with satellite.resources.dllfiles that should not be present alongside the native AOT binary. Binlogs are also included in the build artifacts for investigation.