同一来源,具有不同资源的多个目标(Visual Studio 2008中的.Net)多个、不同、来源、目标

2023-09-03 12:24:33 作者:时光崩断了我所有幻想的逻

这是一套软件产品,他们的资源字符串,二进制资源,并通过串/图形/产品中使用他们的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中的园丁,创先争优的老总,等等。每个产品具有相同的功能,但不同的名称,图形,帮助文件,包括模板等。的

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.

在这些正在兴建的环境是:香草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?

============澄清(S)=====

按产品我的意思是,获取由安装程序安装,并销售给最终用户的软件程序包。

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:

创建一个类库项目(卫星)。 删除默认的cs文件,并添加一个文件夹(默认) 文件夹中创建一个资源文件为MyResources 属性 - 设置CustomToolNamespace的东西 适当的(如XXX) 确保对资源的访问修饰符是公开。加 的资源。编辑源$ C ​​$ C。 请参阅资源在code 作为XXX.MyResources.ResourceName) 创建配置为每个产品变型(ConfigN) 对于每一个产品系列,建立一个文件夹(VariantN) 复制和粘贴为MyResources文件到每个VariantN文件夹 卸载卫星项目,并编辑.csproj的文件 对于每一个VariantN /为MyResources&LT;编译&GT; &LT; EmbeddedResource&GT; 标签, 添加条件='$(配置)'=='ConfigN'属性。 保存,重新加载的.csproj,就完成了...... Create a class library project ("Satellite"). Delete the default .cs file and add a folder ("Default") Create a resource file in the folder "MyResources" Properties - set CustomToolNamespace to something appropriate (e.g. "XXX") 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) Create Configurations for each product variant ("ConfigN") For each product variant, create a folder ("VariantN") Copy and Paste the MyResources file into each VariantN folder Unload the "Satellite" project, and edit the .csproj file For each "VariantN/MyResources" <Compile> or <EmbeddedResource> tag, add a Condition="'$(Configuration)' == 'ConfigN'" attribute. Save, Reload the .csproj, and you're done...

这将创建一个每个配置资源文件,它可以(presumably)进一步本地化。编译错误消息产生对于其中aa资源丢失任何​​配置。资源文件可以使用标准方法(创建第二个资源文件(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="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>

提供的所有访问你的资源是通过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.

不幸的是,我不认为你可以强制资源使用相同基(如提供给ResourceManager的构造函数),因为它是基于项目内的道路上,我不能找到一种方法来覆盖。如果你需要他们使用相同的名称(如果你手动创建ResourceManagers,例如),那么我建议在项目的顶层有一个Resources1.resx(加上相关的CS文件),而不是根据源代码控制。作为pre-build事件,复制的.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 的

在回应查询有关检查每一个资源文件中包含了相同的资源 - 如果你使用的是资源类(如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文件具有相同的文件名中包含相同数量的&lt;数据&GT;元件,具有相同名称的属性

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.