相同的源,具有不同资源的多个目标(Visual Studio .Net 2008)

MZB*_*MZB 13 .net c# visual-studio-2008

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

即所有产品基本上由图形,字符串和其他资源数据定制的相同核心功能组成,以形成每个产品. 想象一下,您正在创建一组产品,如"Excel for Bankers",Excel for Gardeners","Excel for CEOs"等.每个产品都具有相同的功能,但名称,图形,帮助文件,包含的模板等不同.

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

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

希望我错过了做这一切的明显而简单的方法.它是什么?

============澄清================

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

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

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

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

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

  1. 创建一个类库项目("Satellite").
  2. 删除默认的.cs文件并添加文件夹("默认")
  3. 在"MyResources"文件夹中创建资源文件
  4. 属性 - 将CustomToolNamespace设置为适当的值(例如"XXX")
  5. 确保资源的访问修饰符是"Public".添加资源.编辑源代码.请参阅代码中的资源XXX.MyResources.ResourceName)
  6. 为每个产品变体创建配置("ConfigN")
  7. 对于每个产品变体,创建一个文件夹("VariantN")
  8. 将MyResources文件复制并粘贴到每个VariantN文件夹中
  9. 卸载"Satellite"项目,然后编辑.csproj文件
  10. 对于每个"VariantN/MyResources" <Compile><EmbeddedResource>标记,添加一个 Condition="'$(Configuration)' == 'ConfigN'" 属性.
  11. 保存,重新加载.csproj,你就完成了......

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

这是95%解决方案的原因是用于初始化表单的资源(例如表单标题,按钮文本)不能以相同的方式轻松处理 - 最简单的方法似乎是用来自附属程序集的值覆盖这些资源.

Dam*_*ver 11

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

  <ItemGroup>
    <Compile Include="Debug\Resource1.Designer.cs" Condition=" '$(Configuration)' == 'Debug' ">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resource1.resx</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Queue.cs" />
    <Compile Include="Release\Resource1.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="Debug\Resource1.resx" Condition=" '$(Configuration)' == 'Debug' ">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resource1.Designer.cs</LastGenOutput>
      <CustomToolNamespace>Resources</CustomToolNamespace>
    </EmbeddedResource>
    <EmbeddedResource Include="Release\Resource1.resx" Condition=" '$(Configuration)' == 'Release' ">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resource1.Designer.cs</LastGenOutput>
      <CustomToolNamespace>Resources</CustomToolNamespace>
    </EmbeddedResource>
  </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

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

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

编辑

忘记提及(虽然在上面的MSBuild文件摘录中看到)你必须将每个.resx文件上的自定义工具命名空间设置为相同的值(例如参考资料),否则它也默认包含文件夹名称.

编辑2

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

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