Search code examples
c#.netwpfinternationalizationresx

C# WPF implements multi-language internationalization support, and the corresponding resource dll file cannot be generated


I am trying to implement multi-language internationalization support in my C# WPF application. I have followed the guidelines for setup, but I'm encountering an issue when trying to generate the corresponding resource DLL file.

Here are the steps I have tried:

  1. I added WPFLocalizeExtension package for multi-language support.
  2. I wrote a LanguageHelper class to get internationalized strings.
public static string GetLocalizedString(string key, string resourceFileName = "Languages", bool addSpaceAfter = false)
  {
      var localizedString = String.Empty;

      // Build up the fully-qualified name of the key
      var assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
      var fullKey = assemblyName + ":" + resourceFileName + ":" + key;
      var locExtension = new LocExtension(fullKey);
      locExtension.ResolveLocalizedValue(out localizedString);

      // Add a space to the end, if requested
      if (addSpaceAfter)
      {
          localizedString += " ";
      }

      return localizedString;
  }

Returns a string. It has three parameters:

  • key: Keyword or identifier used to specify the localized string to be obtained.
  • resourceFileName: used to specify the name of the resource file, the default value is "Languages".
  • addSpaceAfter: A Boolean value that, if true, adds a space to the end of the localized string.

This method is used to obtain a localized string from the specified resource file (default is "Languages") based on the given key.

  1. Making references in Xaml
lex:LocalizeDictionary.DesignCulture="en-US" 
lex:ResxLocalizationProvider.DefaultAssembly="AppSample" 
lex:ResxLocalizationProvider.DefaultDictionary="Langs"  

Configure WPF's Xaml file to support multiple languages and display corresponding localized resources in different locales.

  1. Use this method to change the language
public void ChangeLanguage(string languageCode)
    {
        WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.Culture = new CultureInfo(languageCode);
    }
  1. Writing .resx files

The configuration details of the .resx file are:

  • The file storage path is the i18n folder, not the Resources folder.
  • The naming is unified as: Languages.en_US.resx
  • All are embedded resources
  • Set Public access modifier for all files
  1. Build project

However, at step 6, I encountered the following issue:

When generating, an error will be reported The file "obj\x64\All\en-US\DarkMode 2.resources.dll" cannot be copied because the file cannot be found.

I have reviewed my code and configuration, but I am still unable to resolve the issue. I am wondering if anyone has encountered a similar issue in a similar context, or if anyone knows how to properly generate the resource DLL file for multi-language support.

Here is the environment and tools I am using:

  • Visual Studio Version: 2022 17.6.2
  • .NET Version: .Net Framework 4.8

My English skills are not good. If you have any questions, please feel free to ask. Any suggestions or guidance on how to resolve this issue would be greatly appreciated. Thank you!

I have tried before:

  1. Delete the obj directory
  2. Clean the solution and rebuild

Solution

  • This problem has been bothering me for many days, until just now when I finally found the cause of the issue. This problem did not exist in the previous version, but it appeared in the recent update. So, I used Git to compare the working trees between the previous version and the current version, and identified the problem. In the previous version, there was no restriction on compiling auxiliary assemblies, which led to this problem in the current version where it was set to always compile auxiliary assemblies. To solve this problem, you just need to set the compilation of auxiliary assemblies to False in the .csproj file of the project.

    <Project>
        <PropertyGroup>
            <GenerateSatelliteAssembliesForCore>false</GenerateSatelliteAssembliesForCore>
        </PropertyGroup>
    </Project>
    

    But there is a problem with this. If you want to build a program for the RAM64 architecture, you must set GenerateSatelliteAssembliesForCore to true, and it will not compile. My solution to this is as follows:

    Write corresponding GenerateSatelliteAssembliesForCore configurations for different architectures.

    <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
        <OutputPath>bin\Out\ARM64\</OutputPath>
        <DefineConstants>TRACE</DefineConstants>
        <Optimize>true</Optimize>
        <DebugType>none</DebugType>
        <PlatformTarget>ARM64</PlatformTarget>
        <LangVersion>preview</LangVersion>
        <ErrorReport>prompt</ErrorReport>
        <Prefer32Bit>true</Prefer32Bit>
        <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
      </PropertyGroup>
      <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
        <OutputPath>bin\Out\x64\</OutputPath>
        <DefineConstants>TRACE</DefineConstants>
        <Optimize>true</Optimize>
        <DebugType>none</DebugType>
        <PlatformTarget>x64</PlatformTarget>
        <LangVersion>preview</LangVersion>
        <ErrorReport>prompt</ErrorReport>
        <Prefer32Bit>true</Prefer32Bit>
        <GenerateSatelliteAssembliesForCore>false</GenerateSatelliteAssembliesForCore>
      </PropertyGroup>
    

    Write another script to copy the corresponding language resource files compiled under the x64 architecture to the corresponding directory under the RAM64 architecture.

    Scripting will not be demonstrated.