相同的源,具有不同资源的多个目标 (Visual Studio .Net 2008) [英] Same source, multiple targets with different resources (Visual Studio .Net 2008)

查看:18
本文介绍了相同的源,具有不同资源的多个目标 (Visual Studio .Net 2008)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一组软件产品的区别仅在于它们的资源字符串、二进制资源以及它们的 Visual Studio 安装项目使用的字符串/图形/产品密钥.创建、组织和维护它们的最佳方式是什么?

A set of software products differ only by their resource strings, binary resources, and by the strings / graphics / product keys used by their Visual Studio Setup projects. What is the best way to create, organize, and maintain them?

即所有产品本质上都由相同的核心功能组成,这些功能通过图形、字符串和其他资源数据定制,以形成每个产品.假设您正在创建一组产品,例如银行家 Excel"、园丁用 Excel"、CEO 用 Excel"等.每个产品都具有相同的功能,但名称、图形、帮助文件不同,包括模板等

i.e. All the products essentially consist of the same core functionality customized by graphics, strings, and other resource data to form each product. Imagine you are creating a set of products like "Excel for Bankers", Excel for Gardeners", "Excel for CEOs", etc. Each product has the the same functionality, but differs in name, graphics, help files, included templates etc.

构建这些的环境是:vanilla Windows.Forms/Visual Studio 2008/C#/.Net.

The environment in which these are being built is: vanilla Windows.Forms / Visual Studio 2008 / C# / .Net.

理想的解决方案应该易于维护.例如如果我引入一个新的字符串/新资源项目,我还没有添加资源应该在编译时失败,而不是运行时.(后续产品国产化应该也是可行的).

The ideal solution would be easy to maintain. e.g. If I introduce a new string / new resource projects I haven't added the resource to should fail at compile time, not run time. (And subsequent localization of the products should also be feasible).

希望我错过了执行所有这些操作的非常明显且简单的方法.它是什么?

Hopefully I've missed the blindingly-obvious and easy way of doing all this. What is it?

============ 说明================

产品"是指由安装程序安装并出售给最终用户的软件包.

By "product" I mean the package of software that gets installed by the installer and sold to the end user.

目前我有一个解决方案,包含多个项目(包括一个安装项目),它构建一组程序集并创建一个安装程序.

Currently I have one solution, consisting of multiple projects, (including a Setup project), which builds a set of assemblies and create a single installer.

我需要生产多个产品/安装程序,它们都具有相似的功能,它们是从同一组程序集构建的,但其中一个程序集使用的资源集不同.这样做的最佳方法是什么?

------------ 95% 的解决方案 -----

------------ The 95% Solution -----------------

根据 Daminen_the_unbeliever 的回答,每个配置的资源文件可以实现如下:

Based upon Daminen_the_unbeliever's answer, a resource file per configuration can be achieved as follows:

  1. 创建一个类库项目(卫星").
  2. 删除默认的 .cs 文件并添加文件夹(默认")
  3. 在文件夹MyResources"中创建一个资源文件
  4. 属性 - 将 CustomToolNamespace 设置为某些内容适当的(例如XXX")
  5. 确保资源的访问修饰符是Public".添加资源.编辑源代码.参考代码中的资源作为 XXX.MyResources.ResourceName)
  6. 为每个产品变体创建配置(ConfigN")
  7. 为每个产品变体创建一个文件夹(VariantN")
  8. 将 MyResources 文件复制并粘贴到每个 VariantN 文件夹中
  9. 卸载卫星"项目,并编辑 .csproj 文件
  10. 对于每个VariantN/MyResources" 标记,添加 Condition="'$(Configuration)' == 'ConfigN'" 属性.
  11. 保存,重新加载 .csproj,你就完成了...
  1. Create a class library project ("Satellite").
  2. Delete the default .cs file and add a folder ("Default")
  3. Create a resource file in the folder "MyResources"
  4. Properties - set CustomToolNamespace to something appropriate (e.g. "XXX")
  5. Make sure the access modifier for the resources is "Public". Add the resources. Edit the source code. Refer to the resources in your code as XXX.MyResources.ResourceName)
  6. Create Configurations for each product variant ("ConfigN")
  7. For each product variant, create a folder ("VariantN")
  8. Copy and Paste the MyResources file into each VariantN folder
  9. Unload the "Satellite" project, and edit the .csproj file
  10. For each "VariantN/MyResources" <Compile> or <EmbeddedResource> tag, add a Condition="'$(Configuration)' == 'ConfigN'" attribute.
  11. Save, Reload the .csproj, and you're done...

这会创建一个每个配置的资源文件,可以(大概)进一步本地化.对于缺少资源的任何配置,都会生成编译错误消息.可以使用标准方法本地化资源文件(创建第二个资源文件 (MyResources.fr.resx) 并像以前一样编辑 .csproj).

This creates a per-configuration resource file, which can (presumably) be further localized. Compile error messages are produced for any configuration that where a a resource is missing. The resource files can be localized using the standard method (create a second resources file (MyResources.fr.resx) and edit .csproj as before).

这是一个 95% 解决方案的原因是用于初始化表单的资源(例如表单标题、按钮文本)不能以相同的方式轻松处理 - 最简单的方法似乎是用来自卫星大会.

The reason this is a 95% solution is that resources used to initialize forms (e.g. Form Titles, button texts) can't be easily handled in the same manner - the easiest approach seems to be to overwrite these with values from the satellite assembly.

推荐答案

您可以向 MSBuild 文件中的元素添加条件.因此,例如,如果您有调试"资源和发布"资源,您可以将它们放在两个单独的文件夹中(例如调试和发布).然后,在您的 MSBuild 文件中,您可能有:

You can add conditionals to elements within the MSBuild file. So for instance, if you have "Debug" resources and "Release" resources, you can place these within two separate folders (e.g. Debug and Release). Then, within your MSBuild file you might have:

  <ItemGroup>
    <Compile Include="DebugResource1.Designer.cs" Condition=" '$(Configuration)' == 'Debug' ">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resource1.resx</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="PropertiesAssemblyInfo.cs" />
    <Compile Include="Queue.cs" />
    <Compile Include="ReleaseResource1.Designer.cs" Condition=" '$(Configuration)' == 'Release' ">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resource1.resx</DependentUpon>
    </Compile>
    <Compile Include="Stack.cs" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="XMLFile1.xml" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="DebugResource1.resx" Condition=" '$(Configuration)' == 'Debug' ">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resource1.Designer.cs</LastGenOutput>
      <CustomToolNamespace>Resources</CustomToolNamespace>
    </EmbeddedResource>
    <EmbeddedResource Include="ReleaseResource1.resx" Condition=" '$(Configuration)' == 'Release' ">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resource1.Designer.cs</LastGenOutput>
      <CustomToolNamespace>Resources</CustomToolNamespace>
    </EmbeddedResource>
  </ItemGroup>

如果您对资源的所有访问都是通过 Resources.Resource1 类进行的,那么您将获得两组不同的资源用于调试和发布版本.显然,这可以扩展到进一步的配置.

Provided all of your access to your resources are via the Resources.Resource1 class, then you get two different sets of resources for debug and release builds. Obviously, this can be extended to further configurations.

不幸的是,我认为您不能强制资源使用相同的 baseName(提供给 ResourceManager 构造函数),因为它基于项目中的路径,我找不到覆盖它的方法.如果您确实需要它们使用相同的名称(例如,如果您手动创建 ResourceManagers),那么我建议在项目的顶层使用 Resources1.resx(加上相关的 cs 文件),而不是在源头控制.作为预构建事件,根据需要从 Debug 或 Release 目录中复制所需的 .resx 文件.(在这种情况下,您可能希望强制它不编译子目录中的 .Designer.cs 文件.

Unfortunately, I don't think you can force the resources to use the same baseName (as provided to ResourceManager constructor), since it's based on the path within the project, and I can't find a way to override that. If you do need them to use the same name (if you're manually creating ResourceManagers, for example), then I'd suggest having a Resources1.resx (plus associated cs file) at the top level of the project, and not under source control. As a pre-build event, copy the required .resx file out from the Debug or Release directory as appropriate. (In this situation, you'd probably want to force it to not compile the .Designer.cs files within the subdirectories.

编辑

忘记提及(尽管在上面的 MSBuild 文件摘录中可以看到)您必须将每个 .resx 文件上的自定义工具命名空间设置为相同的值(例如资源),否则它也默认包含文件夹名字.

Forgot to mention (though it's seen in the above excerpt from the MSBuild file) that you have to set the Custom Tool Namespace on each .resx file to the same value (e.g. Resources), otherwise it also defaults to including the folder name.

编辑 2

响应关于检查每个资源文件是否包含相同资源的查询 - 如果您使用 Resource 类(例如 Resources.Resource1.MyFirstStringResource)来访问您的资源,那么如果需要,切换配置将导致构建错误资源不存在,所以您很快就会发现.

In response to query about checking that each resource file contains the same resources - If you're using the Resource class (e.g. Resources.Resource1.MyFirstStringResource) to access your resources, then switching configurations will result in build errors if the required resource doesn't exist, so you'll find that quite quickly.

对于真正的偏执狂(即,如果您的构建过程需要 3 天的时间来构建所有配置,或者同样疯狂的事情),在一天结束时,.resx 文件只是 XML 文件 - 您只需要检查每个具有相同文件名的 .resx 文件包含相同数量的 <data>元素,具有相同的名称属性.

For the truly paranoid (i.e. if your build process takes 3 days to build all configurations, or something equally mad), at the end of the day, .resx files are just XML files - you just need something to check that each .resx file with the same filename contains the same number of <data> elements, with the same name attributes.

这篇关于相同的源,具有不同资源的多个目标 (Visual Studio .Net 2008)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆