本文介绍了为什么警告 CS1607“为‘产品版本’指定的版本不是正常的‘major.minor.build.revision’格式"?生成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天我收到一个为产品版本"指定的版本不是正常的major.minor.build.revision"格式警告.

AssemblyInformationalVersionAttribute.

我的程序集属性是:

[程序集:AssemblyInformationalVersion("XXX 1.1.0")][程序集: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 可以解决此问题(但我当然不能这样做).

欢迎任何解释.

附注:CS1607:为文件版本"指定的版本不是 .NET 中正常的major.minor.build.revision"格式 问题不相关(与 AssemblyInformationalVersion 无关)>

谢谢汉斯·帕桑特.从您的回答中,我了解到 AssemblyInformationalVersion 用于生成 Win32 VersionInfo 结构中可用的两个 ProductVersion 值.

  • 如果 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

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

然而,非托管产品版本非常麻烦.您可以在 FileVersionInfo 类中看到的内容,该类可让您从可执行文件中读回非托管版本资源.请注意其 ProductVersion 属性如何返回 string.但是 ProductMajorPart(以及次要、构建和私有)属性返回一个 int.

您现在可能已经看到了摩擦.由于一些深不可测的原因,在时间的迷雾中早已消失,版本资源的原始规范包括产品版本两次.一次是二进制数,一次是字符串.字符串可以本地化,这可能是造成这种重复的原因.当您使用非托管资源编辑器查看资源时,您也可以看到这一点.使用 File + Open + File 并选择可执行文件.双击 Version.1 资源.您还将在此对话框中看到产品版本出现两次.上面一个只接受数字,下面一个接受任何字符串.

这让 C# 编译器在没有桨的情况下继续前进,它必须将属性字符串转换为整数,以便它也可以生成二进制数.显然,它不能在不产生警告的情况下就让它出错.MSDN doc for CS1607 中关于这是良性的断言并不是非常准确,您确实最终得到了没有二进制产品版本集的资源.然而,这最终导致麻烦的可能性并不大,其他程序通常不会读回它,而且往往只能由人类查看.该文件的资源管理器属性对话框中的详细信息"属性表将显示它.字符串,而不是二进制数.

因此您需要考虑的解决方法是仅指定一个有效的版本号,因为它确实是一个版本号.或者自己接管非托管资源的生成,以便您完全控制内容.您可以通过编写资源脚本并使用 rc.exe 进行编译来完成.并使用 Project + Properties,Application 选项卡告诉 C# 编译器有关它的信息,选择Resource file"单选按钮.请注意您将给自己造成的巨大痛苦,您现在还需要保持资源脚本更新并与托管资源同步.我会说,对于附属程序集来说尤其痛苦.

Today I'm getting a The version specified for the 'product version' is not in the normal 'major.minor.build.revision' format warning.

It's related to the use of AssemblyInformationalVersionAttribute.

My assembly attributes are:

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

Basically the compiler complains about XXX 1.1.0 that doesn't look like x.y.z.r. From MSDN:

So they say a warning that is harmless can occur. The problem is, it breaks my build. I can't even suppress the CS1607 warning (I tried that at the project level, no effect) as suggested in the following bug http://connect.microsoft.com/VisualStudio/feedback/details/275197/assemblyinformationalversion-should-not-generate-cs1607

Actually, everything was fine (no warning) until I added localized resources to my project. I previously had a MyResources.resx file in the project. I added a localized MyResources.fr.resx file, and this resource is the source of the warning (or at least: if I remove this file from the project, it compiles without warning).

I don't see any link between CS1607 (related to x64 vs x86), AssemblyInformationalVersionAttribute and a localized resource file...

How could I fix my project so I can use XXX 1.1.0 as AssemblyInformationalVersionAttribute without any (even harmless) warning?

I'm not that OK with suppressing the CS1607 warning (that could be useful in case of wrong references), but I didn't even managed to suppress it.

Do note I found it was CS1607 by googling, the compiler never returned the actual warning code.

Also note my project targets .Net 2.0, and moving to .Net 4.0 fixes the issue (but of course I can't do this).

Any explanation is welcome.

PS:CS1607: The version specified for the 'file version' is not in the normal 'major.minor.build.revision' format in .NET is question is not related (not about AssemblyInformationalVersion)


EDIT:Thanks Hans Passant. From your answer, I understand AssemblyInformationalVersion is used to generate the two ProductVersion values available in the Win32 VersionInfo structure.

  • If the AssemblyInformationalVersion attributes is empty, then AssemblyVersion is used instead.
  • If AssemblyInformationalVersion is x.y.z, both ProductVersion values are x.y.z.
  • If AssemblyInformationalVersion is another string, the number value of ProductVersion is not set (0.0.0) and only the textual ProductVersion value is set.

What I do not understand, is why the CS1607 warning is only generated by the compiler under some specific circumstances: in my case only when the project contains localized resx files and targets .Net 2.0.

I used a string in AssemblyInformationalVersion for years without any warning until yesterday, when I added a localized resx to the project.

I'm OK with not having the number ProductVersion value set (as you said, only the textual and human-readable value is important for me), but is there a way to prevent the warning from being raised?


EDIT 2:

I've created a very small solution sample that demonstrates the issue: http://sharesend.com/mb371c3l

  • First compilation: expected CS1607 raised by the compiler.
  • Then remove Logon.aspx.fr.resx and rebuild all: no more warning on my machine, for an unknown reason.

解决方案

The C# compiler does apply an untrivial conversion to these attributes. It needs to generate the unmanaged resources for the executable. Necessary because Windows doesn't know anything about managed resources or attributes. This is normally done automagically. Like the [AssemblyInformationalAttribute] is auto-converted to generate the Version resource's Product version number. Do note the drastic naming mismatch, not a mistake.

The unmanaged product version is however pretty troublesome. Something you see back in the FileVersionInfo class, the one that lets you read back the unmanaged version resource from an executable file. Note how its ProductVersion property returns a string. But the ProductMajorPart (and minor, build and private) property return an int.

You probably see the friction by now. For some unfathomable reason long lost in the fog of time, the original spec of the Version resource included the Product version twice. Once as a binary number, again as a string. The string can be localized, the probable reason for this duplication. You can also see this back when you look at the resource with the unmanaged resource editor. Use File + Open + File and select the executable file. Double click the Version.1 resource. You'll see the Product version appear twice in this dialog as well. The top one only accepts numbers, the bottom one accepts any string.

Which leaves the C# compiler to up the creek without a paddle, it must convert the attribute string to integers so it can generate the binary number as well. Clearly it cannot just let that go wrong without at least generating a warning. The assertion in the MSDN doc for CS1607 that this is benign is not terribly accurate, you really do end up with a resource that doesn't have the binary product version set. The odds that this ends up causing trouble are however not that great, other programs don't usually read it back and it tends to only be looked at by humans. The "Details" property sheet in Explorer's Properties dialog for the file displays it. The string, not the binary number.

So workarounds you need to contemplate is to just specify a valid version number because it really is a version number. Or to take over generation of the unmanaged resource yourself so you have complete control over the content. Which you do by writing a resource script and compile with rc.exe. And tell the C# compiler about it with Project + Properties, Application tab, select the "Resource file" radio button. Do beware the considerable pain you'll inflict on yourself, you now also have the task to keep the resource script updated and in sync with the managed resources. Particularly painful for satellite assemblies I'd say.

这篇关于为什么警告 CS1607“为‘产品版本’指定的版本不是正常的‘major.minor.build.revision’格式"?生成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 20:57