我正在开发一个简单的 C# .NET 4.0 应用程序,并希望将其本地化为多种语言。但是,为本地化创建的附属程序集(即 de/MyApp.resources.dll)会因为必须在这些 dll 及其文件夹周围拖动而破坏其简单性。
这就是为什么我寻找一种方法将这些 dll 包含到主(也是唯一的)程序集中,因此只需要将可执行文件发送给最终用户。我遇到了这个非常有希望的问题并试了一下。
在建议的解决方案中采用该类后,我在预构建命令中使用FART将 .Designer.cs 文件中的所有 ResourceManager 替换为 SingleAssemblyResourceManager:
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 相同。
成功构建它,但它没有按预期工作......表单应该以 InstalledUICulture 语言(如果可用)显示。为此,我在 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 取代。
此外,除了表单按钮的文本之外,我还有每个语言的 strings.resx 文件,用于 MessageBoxes 和诸如此类的东西,而且这两种方式似乎都不起作用。但这可能是另一个问题。
我知道最初的解决方案是为 NET 2.0 环境设计的,并且 ResourceSets 已经过时,但我的理解是它应该可以工作,即使它不推荐。
任何关于我应该研究的地方的指针都会很棒。