1

我正在開發一個簡單的C#.NET 4.0應用程序,並且希望將它本地化爲多種語言。但是,爲本地化而創建的衛星程序集(即de/MyApp.resources.dll)會通過不得不拖動這些dll及其文件夾來破壞其簡單性。C#單一組合多語言應用程序 - 資源未被正確加載

這就是爲什麼我尋找一種方法將這些DLL包含到主要(也是唯一)的程序集中,因此只有可執行文件需要發送給最終用戶。我遇到了this very promising question並給了它一個鏡頭。

採用的建議的解決方案下課後,我更換了所有出現,我可以在構建前命令使用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是相同的。

成功構建它,但它不像預期的那樣工作...表格應該以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不加載適當的資源呢?我檢查了設計器代碼,並且ResourceManager已被SingleAssemblyResourceManager取代。

此外,除了形式按鈕的文本,我有一個每種語言的strings.resx文件,對於MessageBoxes和whatnot,並且這似乎不起作用。但這可能是另一個問題。

我知道原來的解決方案是爲NET 2.0環境設計的,並且ResourceSets已經過時,但我的理解是它應該可以工作,即使它不被推薦。

任何指針,我應該看哪裏將是真棒。

回答

1

事實證明,我最終能夠使其工作,略微修改CurrentUIculture行。這似乎代碼不嘗試父母文化(正確),因爲如果我將它設置爲通用文化(即「德」而不是「DE-DE」)它完美的作品。

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

我發現這一點,因爲這是ApplyResources之間唯一的顯着差異,從的InitializeComponent()和ChangeLanguage()調用。

現在,我不明白爲什麼這樣做,那裏肯定會有更好的解決方案,但它是我迄今發現的唯一解決方案。

的絃樂聲部,雖然仍然不工作:/

+0

我正面臨從.NET 2.0到.NET 4.0改變時,同樣的問題(它的工作與SingleAssemblyComponentResourceManager和.NET 2.0中的魅力) 你的代碼行在調用InitializeComponent()之前;神奇地修復它。儘管如此,絃樂部分仍然不起作用! :/有沒有新的解決方案呢? – Gerrit 2015-04-21 14:17:01

相關問題