65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Compact Framework 2.0 进行资源本地化生存指南

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (14投票s)

2008年7月29日

CPOL

9分钟阅读

viewsIcon

62969

downloadIcon

580

使用 Compact Framework 2.0 和 Visual Studio 2005 创建本地化资源的小指南。

引言

前几天,我完成了一个小型 Pocket PC 时钟应用程序,用于我在另一个城市工作时使用(早上听到 Windows 音乐醒来很无聊)。应用程序效果不错,一位朋友对我说:“为什么不本地化应用程序并出售呢?”对我来说,本地化并不容易,因为尽管框架实现了简单的方法,但CABWiz.exe 应用程序中的一个 bug 使工作变得复杂。

在这里,我将汇集我在不同来源找到的关于在 .NET Compact Framework 2.0 和 Visual Studio 2005 下实现资源本地化方法的精炼信息。

背景

Visual Studio 2005 附带了一个非常实用的资源本地化功能。特别是,您可以将表单中的字符串本地化到不同语言,还可以将内部字符串本地化到单独的资源文件中。

在本文中,我将描述如何将示例项目的表单本地化为三种语言,如何本地化内部字符串,以及如何通过一种变通方法将应用程序 CAB 文件部署到目标设备,以避免 CABWiz bug。

我们以一个简单的应用程序为例,当然就是那个“不可言喻”的 Hello World。我们将应用程序本地化为英语(默认)、德语和西班牙语。应用程序显示一个 Hello 标签和一个按钮,用于打开一个对话框,其中包含本地化语言的“World”一词。

要测试应用程序,您应该将模拟器的本地化更改为正确的语言。

步骤 1:创建测试项目 HelloWorld

创建一个简单的 Windows CE Pocket PC 项目,其中包含您在图 1 中看到的控件。应用程序将在控制面板的所选语言中显示本地化字符串。

Fig 1. Example Program Hello World!

步骤 2:将控件的表单本地化为西班牙语、英语和德语

这是最简单的步骤,Visual Studio 为我们做了一切。要本地化表单,您应该在“表单属性”窗口中修改两个属性。

Language= Select your desired language

Localizable = true;

在“语言”选项中,当您选择“默认”以外的任何项时,都会创建一个新的资源文件,您可以在表单中直接修改所有控件的字符串。在本例中,我已经将表单本地化为英语、德语和西班牙语。

注意:请勿使用本地化表单来移动或修改控件属性。仅使用“默认”表单,除非您希望某个表单的控件具有特定的行为。您可以在“解决方案资源管理器”中Form1.cs 下方看到创建的资源文件。

我们不需要创建英语资源,因为我们将其用作“默认”语言。

.NET Framework 会查找可能的语言资源文件,当找不到匹配项时,它会使用嵌入在程序集中的默认资源。

构建并运行项目。您可以看到表单已本地化为 Pocket PC 的语言(“设置/区域”中的“区域设置”值)。您需要重置模拟器以采用新设置。

有关表单中创建的资源的图 2,以及图 3 中已编译的带资源的卫星程序集,请参见图 2。

Figure 2: Form properties to localize the control in form

Figure 3: Resources files created by Visual Studio

步骤 3:将内部字符串消息本地化为强类型资源

现在,我们加入该功能,当按钮被点击时,显示一个包含“World”一词的消息框表单。对话框包含一个应该被本地化的字符串。

要本地化该字符串,我们需要为每种语言创建一个资源文件。Visual Studio 在properties 目录下方设置默认资源文件。在项目中打开Properties 目录,并查看文件Resources.resx。双击该文件,您将看到资源编辑器。因为我们将英语设置为默认语言,所以我们将英语资源直接输入到此文件中。在编辑器中输入一个值为“World”的字符串资源。

Name = MessageText 
Value= World!

要输入本地化资源,请单击并复制文件Resources.resx,然后在同一目录中创建该文件的副本。将创建的文件重命名为Resources.de.resxResources.es.resx。打开这两个文件,并按以下方式输入资源字符串:

Resources.de.resx
Name = MessageText
Value= Welt!
 
Resources.es.resx
Name = MessageText
Value= Mundo!

对于已添加的资源文件,您应该清除 CustomTool 属性。仅为默认的Resources.resx 文件保留 ResXFileCodeGenerator 值。

重新构建系统;您的“解决方案资源管理器”应该如图所示。

Localized resources files in Solution Explorer

双击按钮以创建 Click_Event,并输入以下简单代码:

private void button1_Click(object sender, EventArgs e)
{
      //Get localized resource and show it in the message Box.
      MessageBox.Show(Properties.Resources.MessageText);
}

在示例中,您可以看到如何以编程方式使用资源。ResXFileCodeGenerator 工具会自动生成一个 Properties.Resources 类来访问资源。框架会自动检测 Pocket PC 的区域设置并获取正确的本地化资源。如果区域设置与现有资源不匹配,则 .NET Framework 会采用默认资源文件中声明的资源语言。

有关更多信息,请查看演示项目中的 Resorce.Designer.cs 文件,其中包含生成类的代码。现在,构建应用程序并针对不同区域设置测试翻译后的值。

步骤 4:生活并不容易:CabWiz bug 变通方法

应用程序的部署部分通常不必处理本地化过程,但由于 VS 2005 附带的CabWiz.exe 应用程序存在 bug,我们需要采取额外步骤来完成此过程。

Visual Studio 2005 的 Cabwiz.exe 程序存在一个众所周知的 bug,我担心(不确定)它也存在于 Visual Studio 2008 [1] 中。查看示例中的HelloWorldCABSetup 项目。如果您部署生成的 CAB,您会发现本地化资源无法正常工作。要测试这一点,请将您的 Pocket PC 语言设置为西班牙语(在控制面板中),然后安装 CAB 文件。您会看到表单字符串仍然是英语。这意味着资源未正确加载。

bug 发生的原因是资源 DLL 文件的名称都相同。当 CABWiz 读取 INF 文件时,它会为所有操作使用相同的 resource.dll 文件,而忽略了它们位于不同目录中且是不同的文件。查看HelloWorldCABSetup 项目中的示例代码。

在参考文献 [1] 中,存在两种解决此问题的方法。以下是一种基于这些方法的解决方案。

要修复此 bug,我们应执行以下步骤:

  1. 在 HelloWorld 项目中,定义一个后期生成操作,以不同的名称复制资源文件。

    您可以使用项目后期生成事件中的命令来复制 DLL。以下是所需代码:

    copy "$(TargetDir)de\HelloWorld.resources.dll"¬ 
    "$(TargetDir)de\DE_HelloWorld.resources.dll"
    copy "$(TargetDir)es\HelloWorld.resources.dll"¬
    "$(TargetDir)es\ES_HelloWorld.resources.dll"

    如果一切正常,您将在成功生成后在资源目录中看到复制的资源。(参见示例。)

    Fig. 5: Post-Build Event in HelloWorld Project

  2. 创建第二个部署项目。

    您可以使用第一个部署项目,但出于演示目的,我在另一个部署项目中进行了更改。我将其命名为HelloWorldCABPatch。像配置第一个部署项目一样配置它,但为新创建的项目分配以下重命名的资源 DLL,而不是原始名称。

    DE_HelloWorld.resources.dll
    ES_HelloWorld.resources.dll

    构建项目,您将在 INF 文件中看到重命名 DLL 的名称。

    [Files.Common1] 
    "DE_HelloWorld.resources.dll","DE_HelloWorld.resources.dll",,0 
    
    [Files.Common2] 
    "ES_HelloWorld.resources.dll","ES_HelloWorld.resources.dll",,0

    显然,我们不能在应用程序中使用这些名称,然后我们应该重命名它们并再次运行CABWiz.exe 文件。

    您可以简单地在 INF 文件中重命名它并手动重新运行CABWiz.exe 实用程序,但这不切实际。我们需要自动完成此过程。

    为此,我们创建了一个小程序来修补 INF 文件并运行CABMWiz.exe

  3. 创建一个控制台程序来修补 INF 文件。

    查看CABWizPatch 下面的代码,该代码仅“修补”INF 文件以生成正确的文件名。(是的,是的,我知道,我使用的方法有点强制,但对于这个例子来说效果非常好。)如果您运行该程序,您会看到 `[Files.Commonx]` 条目被修改,以指示CABWiz.exe 复制具有原始名称的资源文件。您可以在以下代码中看到修改:

    [Files.Common1]
    "HelloWorld.resources.dll","DE_HelloWorld.resources.dll",,0 
    
    [Files.Common2]
    "HelloWorld.resources.dll","ES_HelloWorld.resources.dll",,0
  4. 流程自动化

    您可以通过创建一个虚拟项目并使用预生成事件执行控制台补丁应用程序,以及使用后期生成事件调用CABWiz.exe 来轻松自动化此过程。

    执行此操作的代码是:

    //Pre-build Event
    
    "$(SolutionDir)CABWizPatch\bin\Debug\CABWizPatch.exe"¬
    "$(SolutionDir)HelloWorldCABPatch\Debug\HelloWorldCABPatch.inf"
    
    //Post-Build Event
    
    "C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK¬
    \SDKTools\cabwiz.exe" "$(SolutionDir)HelloWorldCABPatch¬
    \Debug\HelloWorldCABPatch.inf"

在下面的图像中,您可以看到DummyClass 项目的预生成和后期生成事件中的命令。

Fig 5: Pre-Build and Post-Buiel events in DummyClass

注意:请确保您的虚拟类项目在生成过程的最后进行生成。

使用 CAB(位于HelloWorldCABPath/bin/DEBUG 目录下),您将看到您的应用程序现在使用正确的资源值。

如果您想使用 MSI 安装程序,您可以在 MSI 安装程序项目的预生成和后期生成事件中运行补丁组件。现在,当您部署应用程序时,您将看到您的资源在 Pocket PC 上正确显示。

代码

下载并编译文章附带的代码(使用 DEBUG 选项)。

代码和文章中的解释指的是 Debug 编译。您应该为 Release 代码生成调整代码。

项目标识(按顺序)

  1. CABWizPatch:用于修补生成的 INF 文件的控制台应用程序。
  2. DummyClass:类项目,无输出。它用于在预生成事件中运行控制台CABWizPatch,并在后期生成事件中调用CABWiz.exe 应用程序。
  3. HelloWorld:Windows CE 项目,待部署的应用程序。
  4. HelloWorldCABPathHelloWorldCABSetup 的副本,用于演示如何更改部署项目以获取正确的资源 DLL。
  5. HelloWorldCABSetup:原始安装程序,用于演示 CabWiz bug。在实际应用中,您只需要使用 4 个。

请仔细查看代码,您可能需要修改您计算机上的 CABWiz 应用程序的路径。

关注点

在 Visual Studio 2005 中本地化资源的过程很简单,不应该让开发人员头疼。不幸的是,CABwiz 中的一个 bug 可能会给我们带来巨大的困惑,因为我们在 VS2005 下部署时以及使用生成的 CAB 安装应用程序时,我们的工作结果在本地化资源方面与预期完全不同。

本文试图将资源信息汇集在一个地方。希望它能有所帮助。

参考文献

  1. Microsoft Connect. Smart Device CAB project includes wrong localized resources.

历史

  • 2008 年 7 月 30 日 - 首次发布。
© . All rights reserved.