集成LocBaml和MSBuild以及ClickOnce部署

在Visual Studio 2008 SP1环境下测试了以下解决方案,理论上也适用于更早版本的Visual Studio。微软提供了LocBaml.exe工具,但该工具只是一个示例应用程序。这意味着该工具有一些奇怪的行为,目前还没有人构建一个完整的商业应用程序来处理本地化,直到那时被迫使用这个工具。如果想在除了玩具应用程序之外的任何东西中使用它,需要能够生成一个完整的应用程序,包括所有本地化的卫星程序集,每次构建项目时都包括在内。

遇到的障碍

首先,需要将上一次翻译的结果合并回构建中。LocBaml基本上将二进制XAML数据转换为CSV文件。这意味着每次XAML文件的更改都会产生不同的CSV,每次构建后翻译CSV有点繁琐。通过编写一个应用程序(MergeLocBamlCsv)来解决这个问题,它将新生成的CSV与上一次构建的翻译CSV合并。两个应用程序EXE和源代码都包含在压缩文件中。

合并过程很简单:

  1. 解析原始翻译文件
  2. 将每行在逗号处分割成7部分
  3. 记住每行的第7部分,其中包含翻译文本部分。这意味着对于字符串资源或其中第3列不是'None'且文本不以'#'开头(这是一个链接)的字符串,使用前2部分作为键与新CSV文件进行比较。
  4. 用新CSV文件覆盖翻译文件。
  5. 分割新CSV文件的每一行,并比较前2部分。如果它们与翻译CSV的一对匹配,替换第7部分,并将部分用逗号连接成完整的新行。

第二个障碍是CSV文件中不需要翻译的所有内容。在大型程序中,CSV可能会变得杂乱无章,包含细节和“误报(链接)”。为了简化翻译过程,编写了第二个程序(StripLocBamlCsv)来剥离所有不需要翻译的行。这使得到了一个CSV文件,其中每一列都可以翻译,而不是每5-10行翻译1行。两个应用程序EXE和源代码都包含在压缩文件中。

剥离过程更简单:

  1. 解析原始翻译文件
  2. 将每行在逗号处分割成7部分
  3. 检查行是否有(翻译过的)文本部分。这意味着对于字符串资源或其中第3列不是'None'且文本不以'#'开头(这是一个链接)的字符串,将这些行写回,其他所有行都被跳过。

Visual Studio/MSBuild

Visual Studio没有现成的支持为WPF应用程序构建卫星程序集,以进行ClickOnce部署。为了解决这个问题,为LocBaml制作了一个新的项目目标。解决方案只使用XAML文件,不使用自定义resx文件。这与CodeProject文章《使用Locbaml本地化WPF应用程序》中的方法2相对应。建议阅读这篇文章,因为不想重复他关于这种方法的优秀解释。

解决方案

解决方案基于3个应用程序和一个单独的msbuild目标文件:

  • LocBaml.exe
  • MergeLocBamlCsv.exe
  • StripLocBamlCsv.exe
  • LocBaml.Target.xml

它们包含在随本文附带的示例应用程序中。它们只在第二阶段需要,如果有一个原始文化的应用程序。额外的msbuild规则有两个部分:

  1. 添加一个额外的构建动作'LocBamlCsv',这样可以将所有代码放在msbuild文件列表中。
  2. 覆盖'CreateSatelliteAssemblies'目标。这个目标将在EXE构建之后但在应用程序清单创建之前被调用。可以在这里创建卫星程序集,并将它们添加到列表'IntermediateSatelliteAssembliesWithTargetPath'中。完成后,所有DLL文件会自动添加到部署文件中的应用程序清单中。因此,当发布应用程序时,它们会自动添加,无需进行任何额外工作。
%25(LocBamlCsv.Culture) %25(LocBamlCsv.Culture)\$(TargetName).resources.dll

操作步骤

以下是如何使所有内容正常工作的逐步列表。

  1. 构建一个WPF应用程序
  2. 在项目文件中添加标签en-US
  3. 取消注释AssemblyInfo.cs中的NeutralResourcesLanguage行
  4. 在每个XAML文件中添加UID。使用Msbuild /t:updateuid 和Msbuild /t:checkuid 命令
  5. 将应用程序复制到项目目录中的(新)子文件夹Translation中
  6. 将XML文件放置在项目目录的根目录中,并在项目文件中导入。一个很好的位置是在文件末尾的其他导入标签之后。
  7. 在目录中放置一个空的CSV文件,并将构建动作设置为‘LocBamlCsv’
  8. 由于某种原因,无法从Visual Studio更改文化。手动添加正确的Culture到项目文件中的项目,以便得到一个条目,如:nl-NL
  9. 构建应用程序
  10. 翻译步骤7中的CSV文件,它们现在已经填充了
  11. 再次构建,就有了一个本地化的应用程序
  12. 在开始新的翻译之前,不要忘记重复步骤4。否则,构建和发布可以重复进行,无需任何担忧。

示例应用程序

包含了一个示例应用程序,以便有一个功能性的起点。它由一个主应用程序窗口和一个关闭按钮以及一个登录窗口组成。登录窗口底部有一些标志,可以在运行时切换文化。该应用程序目前有3种语言:英语、德语和荷兰语。每个窗口都有一些静态和一些动态文本部分。

切换语言的代码需要重新加载XAML和资源文件,否则即使在UI文化更改后,也会保持相同的语言。因此,窗口被关闭,必须重新显示。其次,合并的字典被清除并重新加载,这重新加载了字符串表。执行此操作的代码如下:

private void btGb_MouseDown(object sender, MouseButtonEventArgs e) { Image img = sender as Image; if(( img != null ) && ( img.Tag != null )) { Thread.CurrentThread.CurrentUICulture = new CultureInfo( (string)img.Tag ); Thread.CurrentThread.CurrentCulture = new CultureInfo( (string)img.Tag ); // Reload all the merged dictionaries to reset the resources. List dictionaryList = new List(); foreach(ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries) { dictionaryList.Add(dictionary.Source); } Application.Current.Resources.MergedDictionaries.Clear(); foreach(Uri uri in dictionaryList) { ResourceDictionary resourceDictionary1 = new ResourceDictionary(); resourceDictionary1.Source = uri; Application.Current.Resources.MergedDictionaries.Add( resourceDictionary1 ); } IsLanguageChange = true; DialogResult = false; Close(); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485