如何修改我的C#项目文件,以便将Resources.resx编译到我的UICulture的附属程序集中?

时间:2012-05-18 18:15:56

标签: wpf visual-studio localization msbuild

我在C#中有一个WPF应用程序,可能需要在将来进行本地化。我想支持XAML / BAML本地化传统的resx本地化。 (前者对大多数代码都很有用,但是一些本地化内容来自视图模型,使用resx文件更直接。)

我已阅读WPF Localization Guidance的相关部分。我在msbuild文件中设置了UICulture属性。我已将以下行添加到AssemblyInfo.cs:

[assembly: NeutralResourcesLanguage("en", UltimateResourceFallbackLocation.Satellite)]

我知道我需要复制 Resources.resx作为Resources.en.resx,以便将我的本地化资源写入附属程序集。

我已将Resources.resx上的构建目标设置为None,并将Resources.en.resx上的构建目标设置为EmbeddedResource。 Resources.resx上的自定义工具是PublicResXFileCodeGenerator,用于生成强类型资源类。我知道生成器只适用于没有文化特定后缀的文件。

目前我必须手动保持Resources.resx和Resources.en.resx同步。它们必须完全相同。 (Rick Stahl explains that here.

我试图修改我的C#项目文件以自动复制文件。但是,我无法让这个工作。我不是msbuild专家!我添加了以下构建目标:

<Target Name="BeforeResGen">
    <Copy SourceFiles="@(CopyAsLocalizedResources)" DestinationFiles="$(IntermediateOutputPath)Resources.$(UICulture).resx">
        <Output ItemName="EmbeddedResource" TaskParameter="DestinationFiles"/>
    </Copy>
</Target>

我将Resources.resx的Build Action从None更改为CopyAsLocalizedResources。

我看到我的Resources.en.resx文件在构建期间被复制到中间目录,但是在运行时找不到我的资源,我得到了一个例外。 Presumaby他们永远不会编入卫星装配。

任何人都可以通过修改项目文件帮助我实现这一目标吗?

2 个答案:

答案 0 :(得分:0)

编译语言dll应位于根据该文化的ISO文化代码命名的文件夹中。此文化命名文件夹应与父组件位于同一目录中。

所以,对于一些foo.dll:

(默认DLL)

仓\ foo.dll

(西班牙(墨西哥)资源)

仓\ ES-MX \ foo.Resources.dll

此文件夹结构和程序集将在编译时进行,因此您只需调整构建后操作即可将culture文件夹中的dll移动到目标目录中的匹配文件夹。

请注意,只需在Visual Studio中使用项目属性在项目构建后步骤框中键入所需的操作,即可通过cp或其他命令行工具执行此移动。

答案 1 :(得分:0)

尤里卡!

  <Target Name="CreateLocalizedResources" BeforeTargets="AssignTargetPaths">
    <Copy SourceFiles="@(CopyAsLocalizedResources)" DestinationFiles="$(IntermediateOutputPath)Resources.$(UICulture).resx" SkipUnchangedFiles="true" UseHardlinksIfPossible="true">
      <Output TaskParameter="DestinationFiles" ItemName="GeneratedLocalizedResources" />
    </Copy>
    <ItemGroup>
      <EmbeddedResource Include="@(GeneratedLocalizedResources)">
        <ManifestResourceName>$(RootNamespace).Properties.Resources.$(UICulture)</ManifestResourceName>
      </EmbeddedResource>
    </ItemGroup>
    <Message Text="Generated resources are: @(GeneratedLocalizedResources)" Importance="high" />
  </Target>

我将我的Resources.resx文件上的Build Action设置为CopyAsLocalizedResources,并且自定义构建目标处理欺骗构建以进行正确的附属程序集。