4

In a VS2015 .NET 4.6.1 project, I have a data resource file with a Build Action set to 'Embedded Resource' and a name as follows:

myDataFile.bin.zip

Unfortunately 'bin' is a locale that is present on my Windows 10 machine, which is causing the file to be identified as a resource for a specific locale, rather than the default one (Visual Studio seems to recognise files named in the format <name>.<locale>.<ext> as being specific to a locale), resulting in the creation of a satellite assembly.

This means that when built, I get two assemblies:

myproject.dll
bin\myproject.resources.dll

I want the file to be included in the project assembly, not in a satellite assembly.

Without changing the filename, is this possible?

Thanks!

Michael Liu
  • 52,147
  • 13
  • 117
  • 150
RSlaughter
  • 1,191
  • 3
  • 11
  • 23

1 Answers1

4

This behavior is implemented by the SplitResourcesByCulture build target in Microsoft.Common.CurrentVersion.targets (located at C:\Program Files (x86)\MSBuild\14.0\Bin) and the Microsoft.Build.Tasks.AssignCulture class. I looked at the source code, but I didn't find a simple switch you can toggle to prevent "bin" from being misinterpreted as a culture name. In fact, for a C# project, the file name is left alone only when the embedded resource is "dependent upon" a like-named .cs file.

So, short of rewriting the standard build targets, you have a simple (if slightly hacky) workaround:

  1. In the folder where myDataFile.bin.zip is located, add to the project an empty C# code file named myDataFile.bin.cs. This name must match the name of your embedded resource exactly except for the final extension (.cs instead of .zip). You can leave the file totally blank, or you can add a comment explaining what's going on:

    // This source file prevents the nested myDataFile.bin.zip file from being treated as
    // a resource for the "bin" culture.
    
  2. Save the project. (To ensure the project file gets saved, click File » Save All.)

  3. Open the .csproj project file in a text editor and locate the <EmbeddedResource> element for myDataFile.bin.zip:

    <EmbeddedResource Include="myDataFile.bin.zip" />
    
  4. Insert a child <DependentUpon> element that references the C# code file:

    <EmbeddedResource Include="myDataFile.bin.zip">
      <DependentUpon>myDataFile.bin.cs</DependentUpon>
    </EmbeddedResource>
    
  5. Save the project file and reload the project in Visual Studio.

  6. Visually confirm in Solution Explorer that myDataFile.bin.zip is nested under myDataFile.bin.cs.

  7. Build the project. Your resource is now embedded in the main assembly instead of a satellite assembly.

Michael Liu
  • 52,147
  • 13
  • 117
  • 150
  • 5
    Note, it seems that in more modern (netcore5+?) the tasks will now respect "WithCulture" metadata, so thus a `` (or a child node `false` does the trick. Merged in: https://github.com/dotnet/msbuild/pull/5824 – admalledd Dec 29 '20 at 07:43
  • @admalledd To make WithCulture works it require MsBuild 16.9 – Cyril Durand Mar 05 '21 at 20:29