1

I have a Windows Forms .NET application in Visual Studio. Making a form "Localizable" adds a Form1.resx file nested below the form. I also want to add a separate .resx file for each form (Form1Resources.resx). This is used for custom form-specific resources, e.g. messages generated using the code behind.

This is set up as follows:

Standard project files

It would be tidier to nest the custom .resx file beneath the form (see this question for details about nest how to do this), as follows:

Project files with nested resx file

However, this results in the following error when I build the application:

Two output file names resolved to the same output path: "obj\Debug\WindowsFormsApp1.Form1.resources" WindowsFormsApp1

I'm guessing that MSBuild uses some logic to find nested .resx files and generate .resources file based on its parent. Is there any way that this can be resolved?

Note that it is not possible to add custom messages to the Form1.resx file - this is for design-specific resources only and any resources that you add get overwritten when you save changes in design mode.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Dan Malcolm
  • 4,382
  • 2
  • 33
  • 27

1 Answers1

1

The error comes from the GenerateResource task because the 2 resx files (EmbeddedResource items in msbuild) passed both have the same ManifestResourceName metadata value. That values gets created by the CreateManifestResourceNames task and assumingly when it sees an EmbeddedResource which has the DependentUpon metadata set (to Form1.cs in your case) it always generates something of the form '$(RootNamespace).%(DependentUpon)': both your resx files end up with WindowsFormsApp1.Form1 as ManifestResourceName. Which could arguably be treated as the reason why having all resx files under Form1 is not tidier: it's not meant for it, requires extra fiddling, moreover it could be confusing for others since they'd typcially expect to contain the resx fils placed beneath a form to contain what it always does.

Anyway: there's at least 2 ways to work around this:

  • there's a Target called CreateCustomManifestResourceNames which is meant to be used for custom ManifestResourceName creation. A bit too much work for your case probably, just mentioning it for completeness
  • manually declare a ManifestResourceName yourself which doesn't clash with the other(s); if the metadata is already present it won't get overwritten by

Generic code sample:

<EmbeddedResource Include="Form1Resources.resx">
  <DependentUpon>Form1.cs</DependentUpon>
  <ManifestResourceName>$(RootNamespace).%(FileName)</ManifestResourceName>
  ...
</EmbeddedResource>
stijn
  • 34,664
  • 13
  • 111
  • 163