c#单汇编多语言应用程序-没有正确加载资源



我正在开发一个简单的c# . net 4.0应用程序,并希望将其本地化为几种语言。然而,为本地化而创建的附属程序集(即de/MyApp.resources.dll)会因为不得不拖拽这些dll及其文件夹而破坏其简洁性。

这就是为什么我寻找一种方法将这些dll包含到主(和唯一)程序集中,所以只有可执行文件需要发送给最终用户。我偶然发现了这个非常有前途的问题,并试了一下。

在建议的解决方案中采用类后,我使用预构建命令中的FART替换了.Designer.cs文件中SingleAssemblyResourceManager中我能找到的所有ResourceManager事件:

fart.exe "$(ProjectDir)*.Designer.cs "System.ComponentModel.ComponentResourceManager" "SingleAssemblyComponentResourceManager"

然后创建一个批处理文件,如下所示:

"%ProgramFiles%ILRepack.exe" /t:exe /out:%1TempProg.exe %1%2.exe %1es%2.resources.dll 
IF %ERRORLEVEL% NEQ 0 GOTO END
"%ProgramFiles%ILRepack.exe" /t:exe /out:%1TempProg2.exe %1TempProg.exe %1de%2.resources.dll
IF %ERRORLEVEL% NEQ 0 GOTO END
"%ProgramFiles%ILRepack.exe" /t:exe /out:%1SA_%2.exe %1TempProg2.exe %1tr%2.resources.dll 
IF %ERRORLEVEL% NEQ 0 GOTO END
del %1%2.exe 
del %1%2.pdb 
del %1TempProg.exe
del %1TempProg.pdb
del %1TempProg2.exe 
del %1TempProg2.pdb 
rmdir %1es /S /Q 
rmdir %1de /S /Q 
rmdir %1tr /S /Q 
:END 

并在构建后的命令中调用它:

$(ProjectDir)postbuild.bat $(TargetDir) $(TargetName)

注意:TargetName和ProjectName在本例中是相同的

成功地构建了它,但它没有像预期的那样工作…该表单应该以installleduiculture语言显示(如果可用)。为了实现这一点,我在InitializeComponent()之前添加了这一行:

Thread.CurrentThread.CurrentUICulture = CultureInfo.InstalledUICulture;

在程序的"标准"版本中起了作用。不再......然而!我还添加了一个小控件,通过ComboBox在运行时更改语言。代码如下:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
  if (comboBox1.SelectedItem.ToString() == "English (Default)")
    {
      Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");
      ChangeLanguage("en");
    }
  else if (comboBox1.SelectedItem.ToString() == "Español")
    {
      Thread.CurrentThread.CurrentUICulture = new CultureInfo("es");
      ChangeLanguage("es");
    }
    else if (comboBox1.SelectedItem.ToString() == "Deutsch")
    {
      Thread.CurrentThread.CurrentUICulture = new CultureInfo("de");
      ChangeLanguage("de");
    }
    else if (comboBox1.SelectedItem.ToString() == "Turkce")
    {
      Thread.CurrentThread.CurrentUICulture = new CultureInfo("tr");
      ChangeLanguage("tr");
    }
}
private void ChangeLanguage(string lang)
{
  foreach (Control c in this.Controls)
  {
    SingleAssemblyComponentResourceManager resources = new SingleAssemblyComponentResourceManager(typeof(Form1));
    resources.ApplyResources(c, c.Name, new CultureInfo(lang));
    if (c.ToString().StartsWith("System.Windows.Forms.GroupBox"))
    {
      foreach (Control child in c.Controls)
      {
          SingleAssemblyComponentResourceManager resources_child = new SingleAssemblyComponentResourceManager(typeof(Form1));
          resources_child.ApplyResources(child, child.Name, new CultureInfo(lang));
      }
    }
  }
}

这个改变了表单语言。所以dll实际上包含在exe中。那么,为什么InitializeComponent不加载适当的资源呢?我检查了Designer代码,发现ResourceManager已经被SingleAssemblyResourceManager取代了。

另外,除了表单按钮的文本,我还有一个字符串。每种语言的resx文件,对于MessageBoxes和诸如此类的东西,这似乎都不起作用。但那可能是另一个问题了。

我知道原来的解决方案是为。2.0环境设计的,而且资源集已经过时了,但我的理解是,它应该工作,即使它不被推荐。

任何关于我应该去哪里看的指示都是很棒的。

事实证明,我最终能够使它工作,稍微修改了CurrentUIculture行。看起来代码没有尝试父区域性(正确地),因为如果我将其设置为通用区域性(即"de"而不是"de- de"),它会完美地工作。

Thread.CurrentThread.CurrentUICulture = new CultureInfo(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName);

我发现了这一点,因为这是InitializeComponent()和changellanguage()的ApplyResources调用之间唯一明显的区别。

现在,我不知道为什么会这样,当然可能有更好的解决方案,但这是目前为止我发现的唯一解决方案。

字符串部分仍然不起作用:/

最新更新