为什么警告CS1607“为'产品版本'指定的版本不是正常的'major.minor.build.revision'格式”生成的?

时间:2013-11-27 11:49:42

标签: c# .net visual-studio-2010 warnings .net-assembly

今天我收到了为“产品版本”指定的版本不符合正常的“major.minor.build.revision”格式警告。

这与使用AssemblyInformationalVersionAttribute

有关

我的程序集属性是:

[assembly: AssemblyInformationalVersion("XXX 1.1.0")]
[assembly: System.Runtime.InteropServices.ComVisible(false)]

编译器基本上抱怨XXX 1.1.0看起来不像x.y.z.r。来自MSDN:

  

信息版提供了其他版本信息   一个汇编,字符串格式。它仅供参考   并且在运行时不使用。虽然您可以指定任何文本,但是   编译时出现警告消息,如果字符串不在   程序集版本号使用的格式,或者是否采用该格式   但包含通配符。这个警告是无害的。

所以他们说可以发出无害的警告。问题是,它破坏了我的构建。我甚至无法抑制CS1607警告(我在项目级别尝试过,没有效果),如下面的错误http://connect.microsoft.com/VisualStudio/feedback/details/275197/assemblyinformationalversion-should-not-generate-cs1607

所示

实际上,在我将本地化资源添加到项目之前,一切都很好(没有警告)。我以前在项目中有一个MyResources.resx文件。我添加了一个本地化的MyResources.fr.resx文件,此资源是警告的来源(或者至少:如果我从项目中删除此文件,它会在没有警告的情况下编译)。

我没有在CS1607(与x64与x86相关),AssemblyInformationalVersionAttribute和本地化资源文件之间看到任何链接......

我如何修复我的项目,以便XXX 1.1.0作为AssemblyInformationalVersionAttribute使用,而不会发出任何(甚至无害的)警告?

我不是那么可以抑制CS1607警告(在错误引用的情况下可能有用),但我甚至没有设法压制它。

请注意我通过谷歌搜索发现它是CS1607,编译器从未返回实际的警告代码。

另请注意我的项目目标.Net 2.0,并转移到.Net 4.0修复了这个问题(当然我不能这样做)。

欢迎任何解释。

PS: CS1607: The version specified for the 'file version' is not in the normal 'major.minor.build.revision' format in .NET问题与此无关(不是关于AssemblyInformationalVersion


编辑: 谢谢Hans Passant。根据您的回答,我了解AssemblyInformationalVersion用于生成Win32 ProductVersion结构中可用的两个VersionInfo值。

  • 如果AssemblyInformationalVersion属性为空,则使用AssemblyVersion代替。
  • 如果AssemblyInformationalVersionx.y.z,则ProductVersion值均为x.y.z
  • 如果AssemblyInformationalVersion是另一个字符串,则ProductVersion的数字值未设置(0.0.0)且仅设置了文字ProductVersion值。

我不明白,为什么 CS1607警告仅在某些特定情况下由编译器生成:在我的情况下只有当项目包含本地化的resx文件和目标.Net时2.0

我在AssemblyInformationalVersion中使用了一个字符串多年没有任何警告,直到昨天我向项目添加了本地化的resx。

我没有设置数字ProductVersion值(如你所说,只有文字和人类可读的值对我来说很重要),但有没有办法防止警告被提出?


编辑2:

我创建了一个非常小的解决方案示例来演示此问题:http://sharesend.com/mb371c3l

  • 首次编译:由编译器引发的预期CS1607。
  • 然后删除Logon.aspx.fr.resx并重建所有内容:由于未知原因,我的计算机上不再发出警告。

1 个答案:

答案 0 :(得分:6)

C#编译器确实对这些属性应用了一个重要的转换。它需要为可执行文件生成非托管资源。这是必要的,因为Windows对托管资源或属性一无所知。这通常是自动完成的。与[AssemblyInformationalAttribute]一样,自动转换为生成版本资源的产品版本号。请注意严重的命名不匹配,而不是错误。

然而,非托管产品版本非常麻烦。您在FileVersionInfo类中看到的东西,它允许您从可执行文件中读回非托管版本资源。请注意其ProductVersion属性如何返回字符串。但是ProductMajorPart(以及minor,build和private)属性返回 int

你现在可能已经看到了摩擦。由于在时间的迷雾中长期丢失的一些不可思议的原因,版本资源的原始规范包括产品版本两次。一旦作为二进制数字,再次作为字符串。字符串可以本地化,这是重复的可能原因。使用非托管资源编辑器查看资源时,您也可以看到此信息。使用File + Open + File并选择可执行文件。双击Version.1资源。您将在此对话框中看到产品版本两次出现。顶部只接受数字,底部接受任何字符串。

这使得C#编译器在没有paddle的情况下离开了creek,它必须将属性字符串转换为整数,这样它也可以生成二进制数。显然,如果不至少产生警告,它就不能让它出错。在MSDN doc for CS1607中声明这是良性的并不是非常准确,你真的最终得到的资源没有设置二进制产品版本。然而,这最终导致麻烦的可能性并不是那么大,其他程序通常不会读回来,而且往往只会被人类看待。 Explorer的“属性”对话框中的“详细信息”属性表显示该文件。字符串,而不是二进制数。

因此,您需要考虑的解决方法是仅指定有效的版本号,因为它确实 是版本号。或者自己接管非托管资源的生成,以便您可以完全控制内容。您可以通过编写资源脚本并使用rc.exe进行编译来完成此操作。并通过Project + Properties,Application选项卡告诉C#编译器,选择“Resource file”单选按钮。请注意您将对自己造成的相当大的痛苦,您现在还要完成保持资源脚本更新并与托管资源同步的任务。对于卫星组件我特别痛苦。