How can I modify my C # project file so that Resources.resx is compiled into the satellite assembly of my UICulture?


I have a WPF application in C# that may need to be localized in the future. I want to support XAML/BAML localization and conventional resx localization. (The former is useful for most of the code, but some localized content comes from the view model, where it is more straightforward to use resx files.)

I have read the relevant parts of the WPF Localization Guidance. I have set the UICulture property in the msbuild file. I have added the following line to AssemblyInfo.cs:

[assembly: NeutralResourcesLanguage("en", UltimateResourceFallbackLocation.Satellite)]

I understand that I need to copy Resources.resx as Resources.en.resx so that my localized resources get written to the satellite assembly.

I have set the build target on Resources.resx to None and on Resources.en.resx to EmbeddedResource. The custom tool on Resources.resx is PublicResXFileCodeGenerator to generate the strongly typed resources class. I know that the generator only works on a file that doesn't have a culture-specific suffix.

At the moment I must manually keep Resources.resx and Resources.en.resx synchronized. They must be identical. (Rick Stahl explains that here.)

I have tried to modify my C# project file to copy the file automatically. However, I can't get this to work. I'm no msbuild expert! I added the following build target:

<Target Name="BeforeResGen">
    <Copy SourceFiles="@(CopyAsLocalizedResources)" DestinationFiles="$(IntermediateOutputPath)Resources.$(UICulture).resx">
        <Output ItemName="EmbeddedResource" TaskParameter="DestinationFiles"/>

I changed the Build Action for Resources.resx from None to CopyAsLocalizedResources.

I see my Resources.en.resx file being copied to the intermediate directory during build, but my resources aren't found at runtime, and I get an exception. Presumaby they are never being compiled into the satellite assembly.

Can anyone help me achieve this using a modification to the project file?

The compiled language dll is expected to be in a folder named according to the ISO culture code for that culture. This culture-named folder is expected to be in the same directory as the parent assembly.

So, for some foo.dll:

(Default DLL)


(Spanish(Mexico) Resources)


This folder structure and assembly will be made at compilation, so you just need to tweak your post-build action to move the dll in the culture folder to a matching folder in your target directory.

Note that you can perform this move via cp or other command line tools simply by typing the actions you need in the project post-build step box with the project properties in Visual Studio.