Program Tip

AssemblyVersion, AssemblyFileVersion 및 AssemblyInformationalVersion의 차이점은 무엇입니까?

programtip 2020. 9. 28. 09:59
반응형

AssemblyVersion, AssemblyFileVersion 및 AssemblyInformationalVersion의 차이점은 무엇입니까?


세 가지 어셈블리 버전 속성이 있습니다. 차이점은 무엇입니까? AssemblyVersion나머지는 사용 하고 무시해도 괜찮 습니까?


MSDN 말한다 :

  • AssemblyVersion :

    어트 리뷰 션되는 어셈블리의 버전을 지정합니다.

  • AssemblyFileVersion :

    Win32 파일 버전 리소스에 특정 버전 번호를 사용하도록 컴파일러에 지시합니다. Win32 파일 버전은 어셈블리의 버전 번호와 같을 필요가 없습니다.

  • AssemblyInformationalVersion :

    어셈블리 매니페스트에 대한 추가 버전 정보를 정의합니다.


이것은 어셈블리 속성을 사용하기위한 모범 사례는 무엇입니까? 의 후속 작업입니다.


AssemblyVersion

어셈블리를 참조하는 다른 어셈블리가 표시됩니다. 이 번호가 변경되면 다른 어셈블리가 해당 어셈블리에 대한 참조를 업데이트해야합니다! AssemblyVersion필요합니다.

저는 major.minor 형식을 사용합니다 . 결과는 다음과 같습니다.

[assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

배포에 사용됩니다. 모든 배포에 대해이 수를 늘릴 수 있습니다. 설치 프로그램에서 사용합니다. 동일한 AssemblyVersion을 갖지만 다른 빌드에서 생성 된 어셈블리를 표시하는 데 사용 합니다.

Windows에서는 파일 속성에서 볼 수 있습니다.

가능하면 MSBuild에서 생성하도록합니다. AssemblyFileVersion은 선택 사항입니다. 지정하지 않으면 AssemblyVersion이 사용됩니다.

저는 major.minor.revision.build 형식을 사용합니다. 여기서 개발 단계 (알파, 베타, RC 및 RTM), 서비스 팩 및 핫픽스를위한 개정을 사용합니다. 결과는 다음과 같습니다.

[assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

어셈블리의 제품 버전입니다. 고객과 대화 할 때 또는 웹 사이트에 표시 할 때 사용하는 버전입니다. 이 버전은 ' 1.0 Release Candidate ' 와 같은 문자열 일 수 있습니다 .

코드 분석은 (CA2243)에 대해 불평을합니다 - 마이크로 소프트에보고 (VS2013에 고정되지 않음).

AssemblyInformationalVersion선택 사항입니다. 지정하지 않으면 AssemblyFileVersion이 사용됩니다.

저는 major.minor [revision as string] 형식을 사용합니다 . 결과는 다음과 같습니다.

[assembly: AssemblyInformationalVersion("1.0 RC1")]

.NET에서 어셈블리의 버전 관리는 현재 어셈블리의 버전을 지정하는 방법이 세 가지 이상 있다는 점을 고려할 때 혼란 스러울 수 있습니다.

다음은 세 가지 주요 버전 관련 어셈블리 특성입니다.

// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]

관례 적으로 버전의 네 부분은 주 버전 , 부 버전 , 빌드수정 버전 이라고합니다 .

AssemblyFileVersion고유의 빌드를 확인하기위한 것입니다 각각의 조립

일반적으로 어셈블리 버전을 반영하도록 Major 및 Minor AssemblyFileVersion을 수동으로 설정 한 다음 빌드 시스템이 어셈블리를 컴파일 할 때마다 빌드 및 / 또는 개정을 증가시킵니다. AssemblyFileVersion을 사용하면 어셈블리 빌드를 고유하게 식별 할 수 있으므로 문제를 디버깅하기위한 시작점으로 사용할 수 있습니다.

현재 프로젝트에서 빌드 서버가 소스 제어 저장소의 변경 목록 번호를 AssemblyFileVersion의 빌드 및 수정 부분으로 인코딩합니다. 이를 통해 빌드 서버에서 생성 된 모든 어셈블리에 대해 어셈블리에서 소스 코드로 직접 매핑 할 수 있습니다 (소스 제어에서 레이블이나 분기를 사용하거나 릴리스 된 버전의 레코드를 수동으로 유지하지 않고도).

이 버전 번호는 Win32 버전 리소스에 저장되며 어셈블리에 대한 Windows 탐색기 속성 페이지를 볼 때 볼 수 있습니다.

CLR은 AssemblyFileVersion을 고려하거나 검사하지 않습니다.

AssemblyInformationalVersion전체 제품의 버전을 표현하기위한 것입니다

AssemblyInformationalVersion은 전체 제품의 일관된 버전 관리를 허용하기위한 것으로, 버전 관리 정책이 다를 수 있고 잠재적으로 서로 다른 팀에서 개발할 수있는 여러 어셈블리로 구성 될 수 있습니다.

예를 들어, 제품 버전 2.0에는 여러 어셈블리가 포함될 수 있습니다. 이러한 어셈블리 중 하나는 동일한 제품의 버전 1.0에서 제공되지 않은 새 어셈블리이므로 버전 1.0으로 표시됩니다. 일반적으로 제품의 공개 버전을 나타내도록이 버전 번호의 주 및 부 부분을 설정합니다. 그런 다음 모든 어셈블리와 함께 완전한 제품을 패키징 할 때마다 빌드 및 개정 부품을 증가시킵니다.” — Jeffrey Richter, [CLR을 통한 C # (Second Edition)] p. 57

CLR은 AssemblyInformationalVersion을 고려하거나 검사하지 않습니다.

AssemblyVersion유일한 버전에 대한 CLR의 염려 (그러나 그것은 전체에 대한 관심 AssemblyVersion)

The AssemblyVersion is used by the CLR to bind to strongly named assemblies. It is stored in the AssemblyDef manifest metadata table of the built assembly, and in the AssemblyRef table of any assembly that references it.

This is very important, because it means that when you reference a strongly named assembly, you are tightly bound to a specific AssemblyVersion of that assembly. The entire AssemblyVersion must be an exact match for the binding to succeed. For example, if you reference version 1.0.0.0 of a strongly named assembly at build-time, but only version 1.0.0.1 of that assembly is available at runtime, binding will fail! (You will then have to work around this using Assembly Binding Redirection.)

Confusion over whether the entire AssemblyVersion has to match. (Yes, it does.)

There is a little confusion around whether the entire AssemblyVersion has to be an exact match in order for an assembly to be loaded. Some people are under the false belief that only the Major and Minor parts of the AssemblyVersion have to match in order for binding to succeed. This is a sensible assumption, however it is ultimately incorrect (as of .NET 3.5), and it’s trivial to verify this for your version of the CLR. Just execute this sample code.

On my machine the second assembly load fails, and the last two lines of the fusion log make it perfectly clear why:

.NET Framework Version: 2.0.50727.3521
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
Successfully loaded assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
Assembly binding for  failed:
System.IO.FileLoadException: Could not load file or assembly 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, 
PublicKeyToken=0b3305902db7183f' or one of its dependencies. The located assembly's manifest definition 
does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f'

=== Pre-bind state information ===
LOG: User = Phoenix\Dani
LOG: DisplayName = Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
 (Fully-specified)
LOG: Appbase = [...]
LOG: Initial PrivatePath = NULL
Calling assembly : AssemblyBinding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
LOG: Attempting download of new URL [...].
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

I think the source of this confusion is probably because Microsoft originally intended to be a little more lenient on this strict matching of the full AssemblyVersion, by matching only on the Major and Minor version parts:

“When loading an assembly, the CLR will automatically find the latest installed servicing version that matches the major/minor version of the assembly being requested.” — Jeffrey Richter, [CLR via C# (Second Edition)] p. 56

This was the behaviour in Beta 1 of the 1.0 CLR, however this feature was removed before the 1.0 release, and hasn’t managed to re-surface in .NET 2.0:

“Note: I have just described how you should think of version numbers. Unfortunately, the CLR doesn’t treat version numbers this way. [In .NET 2.0], the CLR treats a version number as an opaque value, and if an assembly depends on version 1.2.3.4 of another assembly, the CLR tries to load version 1.2.3.4 only (unless a binding redirection is in place). However, Microsoft has plans to change the CLR’s loader in a future version so that it loads the latest build/revision for a given major/minor version of an assembly. For example, on a future version of the CLR, if the loader is trying to find version 1.2.3.4 of an assembly and version 1.2.5.0 exists, the loader with automatically pick up the latest servicing version. This will be a very welcome change to the CLR’s loader — I for one can’t wait.” — Jeffrey Richter, [CLR via C# (Second Edition)] p. 164 (Emphasis mine)

As this change still hasn’t been implemented, I think it’s safe to assume that Microsoft had back-tracked on this intent, and it is perhaps too late to change this now. I tried to search around the web to find out what happened with these plans, but I couldn’t find any answers. I still wanted to get to the bottom of it.

So I emailed Jeff Richter and asked him directly — I figured if anyone knew what happened, it would be him.

He replied within 12 hours, on a Saturday morning no less, and clarified that the .NET 1.0 Beta 1 loader did implement this ‘automatic roll-forward’ mechanism of picking up the latest available Build and Revision of an assembly, but this behaviour was reverted before .NET 1.0 shipped. It was later intended to revive this but it didn’t make it in before the CLR 2.0 shipped. Then came Silverlight, which took priority for the CLR team, so this functionality got delayed further. In the meantime, most of the people who were around in the days of CLR 1.0 Beta 1 have since moved on, so it’s unlikely that this will see the light of day, despite all the hard work that had already been put into it.

The current behaviour, it seems, is here to stay.

It is also worth noting from my discussion with Jeff that AssemblyFileVersion was only added after the removal of the ‘automatic roll-forward’ mechanism — because after 1.0 Beta 1, any change to the AssemblyVersion was a breaking change for your customers, there was then nowhere to safely store your build number. AssemblyFileVersion is that safe haven, since it’s never automatically examined by the CLR. Maybe it’s clearer that way, having two separate version numbers, with separate meanings, rather than trying to make that separation between the Major/Minor (breaking) and the Build/Revision (non-breaking) parts of the AssemblyVersion.

The bottom line: Think carefully about when you change your AssemblyVersion

The moral is that if you’re shipping assemblies that other developers are going to be referencing, you need to be extremely careful about when you do (and don’t) change the AssemblyVersion of those assemblies. Any changes to the AssemblyVersion will mean that application developers will either have to re-compile against the new version (to update those AssemblyRef entries) or use assembly binding redirects to manually override the binding.

  • Do not change the AssemblyVersion for a servicing release which is intended to be backwards compatible.
  • Do change the AssemblyVersion for a release that you know has breaking changes.

Just take another look at the version attributes on mscorlib:

// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]

Note that it’s the AssemblyFileVersion that contains all the interesting servicing information (it’s the Revision part of this version that tells you what Service Pack you’re on), meanwhile the AssemblyVersion is fixed at a boring old 2.0.0.0. Any change to the AssemblyVersion would force every .NET application referencing mscorlib.dll to re-compile against the new version!


AssemblyVersion pretty much stays internal to .NET, while AssemblyFileVersion is what Windows sees. If you go to the properties of an assembly sitting in a directory and switch to the version tab, the AssemblyFileVersion is what you'll see up top. If you sort files by version, this is what's used by Explorer.

The AssemblyInformationalVersion maps to the "Product Version" and is meant to be purely "human-used".

AssemblyVersion is certainly the most important, but I wouldn't skip AssemblyFileVersion, either. If you don't provide AssemblyInformationalVersion, the compiler adds it for you by stripping off the "revision" piece of your version number and leaving the major.minor.build.


AssemblyInformationalVersion and AssemblyFileVersion are displayed when you view the "Version" information on a file through Windows Explorer by viewing the file properties. These attributes actually get compiled in to a VERSION_INFO resource that is created by the compiler.

AssemblyInformationalVersion is the "Product version" value. AssemblyFileVersion is the "File version" value.

The AssemblyVersion is specific to .NET assemblies and is used by the .NET assembly loader to know which version of an assembly to load/bind at runtime.

Out of these, the only one that is absolutely required by .NET is the AssemblyVersion attribute. Unfortunately it can also cause the most problems when it changes indiscriminately, especially if you are strong naming your assemblies.


To keep this question current it is worth highlighting that AssemblyInformationalVersion is used by NuGet and reflects the package version including any pre-release suffix.

For example an AssemblyVersion of 1.0.3.* packaged with the asp.net core dotnet-cli

dotnet pack --version-suffix ci-7 src/MyProject

Produces a package with version 1.0.3-ci-7 which you can inspect with reflection using:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);

It's worth noting some other things:

1) As shown in Windows Explorer Properties dialog for the generated assembly file, there are two places called "File version". The one seen in the header of the dialog shows the AssemblyVersion, not the AssemblyFileVersion.

In the Other version information section, there is another element called "File Version". This is where you can see what was entered as the AssemblyFileVersion.

2) AssemblyFileVersion is just plain text. It doesn't have to conform to the numbering scheme restrictions that AssemblyVersion does (<build> < 65K, e.g.). It can be 3.2.<release tag text>.<datetime>, if you like. Your build system will have to fill in the tokens.

Moreover, it is not subject to the wildcard replacement that AssemblyVersion is. If you just have a value of "3.0.1.*" in the AssemblyInfo.cs, that is exactly what will show in the Other version information->File Version element.

3) I don't know the impact upon an installer of using something other than numeric file version numbers, though.


When a assembly' s AssemblyVersion is changed, If it has strong name, the referencing assemblies need to be recompiled, otherwise the assembly does not load! If it does not have strong name, if not explicitly added to project file, it will not be copied to output directory when build so you may miss depending assemblies, especially after cleaning the output directory.

참고URL : https://stackoverflow.com/questions/64602/what-are-differences-between-assemblyversion-assemblyfileversion-and-assemblyin

반응형