DLL
compile
.NET
culture folders
software development

Disable Dll Culture Folders on Compile

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When building .NET applications, satellite assemblies for localized resources (e.g., fr/, de/, es/ folders) are created in the output directory. To disable these culture folders, exclude unwanted resource assemblies from NuGet packages in your .csproj file using <ExcludeAssets> or <SatelliteResourceLanguages>. This reduces deployment size and simplifies the output directory for applications that do not need multi-language support.

The Problem

After building a .NET project, the output directory contains folders like:

 
1bin/Release/net8.0/
2├── MyApp.dll
3├── MyApp.exe
4├── cs/
5│   └── Microsoft.CodeAnalysis.CSharp.resources.dll
6├── de/
7│   └── Microsoft.CodeAnalysis.CSharp.resources.dll
8├── es/
9│   └── Microsoft.CodeAnalysis.CSharp.resources.dll
10├── fr/
11│   └── Microsoft.CodeAnalysis.CSharp.resources.dll
12├── ja/
13│   └── Microsoft.CodeAnalysis.CSharp.resources.dll
14... (20+ language folders)

These folders contain satellite assemblies — localized resource DLLs for NuGet packages. Most applications only need one or two languages.

Add <SatelliteResourceLanguages> to your .csproj to keep only specific languages:

xml
1<Project Sdk="Microsoft.NET.Sdk">
2  <PropertyGroup>
3    <TargetFramework>net8.0</TargetFramework>
4    <!-- Only include English resources -->
5    <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
6  </PropertyGroup>
7</Project>
xml
<!-- Multiple languages -->
<SatelliteResourceLanguages>en;fr;de</SatelliteResourceLanguages>

This removes all culture folders except the specified languages. Setting it to en effectively removes all folders since English is the default embedded in the main assembly.

Fix 2: ExcludeAssets on Specific Packages

If only certain NuGet packages produce unwanted culture folders:

xml
1<ItemGroup>
2  <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0">
3    <ExcludeAssets>runtime</ExcludeAssets>
4  </PackageReference>
5</ItemGroup>

Or exclude only satellite assemblies from specific packages:

xml
1<ItemGroup>
2  <PackageReference Include="SomePackage" Version="1.0.0">
3    <ExcludeAssets>contentFiles</ExcludeAssets>
4  </PackageReference>
5</ItemGroup>

Fix 3: Delete in Post-Build Event

For cases where MSBuild properties do not work:

xml
1<Target Name="RemoveCultureFolders" AfterTargets="Build">
2  <ItemGroup>
3    <CultureFolders Include="$(OutputPath)*\*.resources.dll" />
4  </ItemGroup>
5  <Delete Files="@(CultureFolders)" />
6  <RemoveDir Directories="@(CultureFolders->'%(RootDir)%(Directory)')" />
7</Target>

Or use a simpler post-build command:

xml
1<PropertyGroup>
2  <PostBuildEvent>
3    for /d %%d in ("$(TargetDir)*") do (
4      if exist "%%d\*.resources.dll" rd /s /q "%%d"
5    )
6  </PostBuildEvent>
7</PropertyGroup>

Fix 4: Directory.Build.props (Solution-Wide)

Apply to all projects in a solution by creating a Directory.Build.props file at the solution root:

xml
1<!-- Directory.Build.props -->
2<Project>
3  <PropertyGroup>
4    <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
5  </PropertyGroup>
6</Project>

Every project in the directory tree inherits this setting automatically.

Fix 5: Publish with Trimming

When publishing, you can control which resources are included:

bash
# Publish with specific culture
dotnet publish -c Release -r win-x64 /p:SatelliteResourceLanguages=en
xml
1<!-- In .csproj for self-contained publish -->
2<PropertyGroup>
3  <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
4  <PublishSingleFile>true</PublishSingleFile>
5  <SelfContained>true</SelfContained>
6</PropertyGroup>

Verifying the Fix

bash
1# Build and check output
2dotnet build -c Release
3
4# List culture folders (should be empty after fix)
5ls bin/Release/net8.0/
6
7# Or on Windows
8dir bin\Release\net8.0\ /ad

When You Need Culture Folders

If your application supports multiple languages, keep the culture folders for those languages:

xml
<!-- Keep English, French, and German -->
<SatelliteResourceLanguages>en;fr;de</SatelliteResourceLanguages>
csharp
1// Loading localized resources at runtime
2using System.Globalization;
3using System.Resources;
4
5// Set culture
6Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr");
7
8// Resources automatically load from fr/ folder
9var rm = new ResourceManager("MyApp.Resources.Strings", typeof(Program).Assembly);
10string greeting = rm.GetString("Hello");  // Loads from fr/MyApp.resources.dll

Common Pitfalls

  • Removing all languages when localization is needed: Setting SatelliteResourceLanguages=en removes all non-English resources. If your app displays localized text from NuGet packages (e.g., validation messages from ASP.NET), users see English regardless of their locale.
  • Culture folders reappearing after dotnet restore: NuGet restores satellite assemblies on every restore. MSBuild properties like SatelliteResourceLanguages are the correct fix because they filter during build, not by deleting files afterward.
  • Post-build scripts not running in CI: Post-build events may use Windows-specific commands (for /d, rd) that fail on Linux CI agents. Use MSBuild targets with <Delete> and <RemoveDir> tasks for cross-platform compatibility.
  • Confusing satellite assemblies with your own resources: SatelliteResourceLanguages affects both your project's resource files (.resx) and NuGet package satellite assemblies. If you have your own French resources, setting SatelliteResourceLanguages=en removes them too.
  • Breaking runtime behavior silently: Removing satellite assemblies does not cause exceptions. Instead, the application silently falls back to the default (invariant/English) culture. This can be hard to detect in testing if you do not explicitly test with non-English locales.

Summary

  • Add <SatelliteResourceLanguages>en</SatelliteResourceLanguages> to .csproj to remove all culture folders
  • Use Directory.Build.props to apply the setting across all projects in a solution
  • Specify multiple languages (en;fr;de) if your app needs localization for those cultures
  • Avoid post-build delete scripts — use MSBuild properties for reliable cross-platform behavior
  • Verify the output with dotnet build and check the output directory for remaining culture folders

Course illustration
Course illustration

All Rights Reserved.