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


860

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


MSDN의 말 :

  • 조립 버전 :

    기여할 어셈블리의 버전을 지정합니다.

  • AssemblyFileVersion :

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

  • AssemblyInformationalVersion :

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


다음은 어셈블리 속성을 사용하는 가장 좋은 방법은 무엇입니까?

답변:


907

조립 버전

어셈블리를 참조하는 다른 어셈블리가 표시되는 위치 이 수가 변경되면 다른 어셈블리는 어셈블리에 대한 참조를 업데이트해야합니다! 이전 버전과 호환되지 않는 경우에만이 버전을 업데이트하십시오. 이 AssemblyVersion필요합니다.

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

[assembly: AssemblyVersion("1.0")]

SemVer를 엄격하게 따르는 경우 1.0, 2.0, 3.0 등 주요 변경 사항이 있을 때만 업데이트됩니다 .

AssemblyFileVersion

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

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

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

나는 major.minor.patch.build 형식을 사용합니다. 여기서 처음 세 부분은 SemVer 를 따르고 마지막 부분은 빌드 서버의 빌드 번호를 사용합니다 (로컬 빌드의 경우 0). 결과는 다음과 같습니다.

[assembly: AssemblyFileVersion("1.3.2.254")]

주의 그 System.Version의 이름이 부품 등major.minor.build.revision !

조립 정보 버전

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

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

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

[assembly: AssemblyInformationalVersion("1.0 RC1")]

4
AssemblyFileVersion의 경우 "가능한 경우 MSBuild에서 생성하도록하십시오"-왜 그렇습니까? 당신은 그것을 수동으로 제어
해야하는

3
AssemblyInformationalVersion 형식에 대한 경고는 오늘 VS2010 (2013 년 5 월 21 일)에 여전히 존재하며 연결이 끊어졌습니다.
reinierpost

22
불행하게도 버전 클래스 정의 major.minor[.build[.revision]]가 아니라 major.minor.revision.build당신이 클래스 속성을 사용한 경우, 또는 빌드 및 개정 번호가 교체 될 것입니다 주어진 대답 그래서 System.Reflection.Assembly.GetExecutingAssembly().GetName().Version빌드 및 개정 번호를 감지 할 수 있습니다.
thinkOfaNumber

9
@thinkOfaNumber 버전 클래스에 대한 귀하의 권리는 Microsoft의 버전 관리 방식입니다. 개인적으로 끝에 빌드 번호가없는 것이 이상하다고 생각하므로 Semantic Versioning 기반으로 형식을 예제로만 사용 합니다. Microsoft 방식이나 자신의 방식을 자유롭게 사용할 수 있습니다.
Rémy van Duijkeren

6
for AssemblyInformationalVersion를 생략하면 AssemblyFileVersion사용됩니다. 그런 다음 AssemblyVersion 둘 다 생략하면.
Drazen Bjelovuk

588

.NET에서 어셈블리의 버전 관리는 현재 어셈블리의 버전을 지정하는 방법이 적어도 3 가지 있다는 점에서 혼란 스러울 수 있습니다.

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

// 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, [C # (제 2 판)을 통한 CLR] p. 57

CLR은 AssemblyInformationalVersion을 신경 쓰거나 검사하지 않습니다.

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

AssemblyVersion은 CLR에서 강력한 이름의 어셈블리에 바인딩하는 데 사용됩니다. 빌드 된 어셈블리의 AssemblyDef Manifest 메타 데이터 테이블 및이를 참조하는 어셈블리의 AssemblyRef 테이블에 저장됩니다.

강력한 이름의 어셈블리를 참조 할 때 해당 어셈블리의 특정 AssemblyVersion에 밀접하게 바인딩되어 있기 때문에 이것은 매우 중요합니다. 바인딩이 성공하려면 전체 AssemblyVersion이 정확히 일치해야합니다. 예를 들어, 빌드 타임에 강력한 이름의 어셈블리 버전 1.0.0.0을 참조하지만 런타임에 해당 어셈블리의 버전 1.0.0.1 만 사용할 수있는 경우 바인딩이 실패합니다! 그런 다음 어셈블리 바인딩 리디렉션을 사용하여이 문제를 해결해야합니다 .

전체 AssemblyVersion가 일치 해야하는지에 대한 혼란 . (그렇습니다)

어셈블리를로드하기 위해 전체 AssemblyVersion이 정확히 일치해야하는지에 대해 약간의 혼동이 있습니다. 어떤 사람들은 구속력을 얻기 위해 AssemblyVersion의 Major와 Minor 부분 만 일치해야한다는 잘못된 믿음 아래 있습니다. 이것은 현명한 가정이지만 궁극적으로 (.NET 3.5 기준) 올바르지 않으며 CLR 버전에 대해 이것을 확인하는 것은 쉽지 않습니다. 이 샘플 코드를 실행 하십시오 .

내 컴퓨터에서 두 번째 어셈블리로드가 실패하고 퓨전 로그의 마지막 두 줄이 이유를 완벽하게 알 수 있습니다.

.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.

이 혼란의 근원은 아마도 Microsoft가 원래 Major 및 Minor 버전 부분에서만 일치시킴으로써 전체 AssemblyVersion의 엄격한 일치에 대해 조금 더 관대하게 의도했기 때문일 것입니다.

"조립품을로드 할 때 CLR은 요청 된 조립품의 주 / 부 버전과 일치하는 최신 설치 서비스 버전을 자동으로 찾습니다." — Jeffrey Richter, [C # (제 2 판)을 통한 CLR] p. 56

이는 1.0 CLR 베타 1의 동작이지만이 기능은 1.0 릴리스 이전에 제거되었으며 .NET 2.0에서는 다시 표면화되지 않았습니다.

“참고 : 버전 번호를 어떻게 생각해야하는지 설명했습니다. 불행히도 CLR은이 방법으로 버전 번호를 처리하지 않습니다. [.NET 2.0]에서 CLR은 버전 번호를 불투명 한 값으로 취급하고 어셈블리가 다른 어셈블리의 버전 1.2.3.4에 의존하는 경우 CLR은 버전 1.2.3.4 만로드하려고합니다 (바인딩 리디렉션이없는 경우) ). 그러나 Microsoft는 특정 버전의 어셈블리에 대한 최신 빌드 / 리비전을로드 할 수 있도록 향후 버전에서 CLR 로더를 변경할 계획입니다.. 예를 들어, 차후 버전의 CLR에서 로더가 어셈블리의 버전 1.2.3.4를 찾고 1.2.5.0 버전이 있으면 로더는 최신 서비스 버전을 자동으로 선택합니다. 이것은 CLR 로더에 대한 매우 환영받는 변화가 될 것입니다. 저는 기다릴 수 없습니다.” — Jeffrey Richter, [C # (제 2 판)을 통한 CLR] p. 164 (공포 광산)

이 변경 사항이 아직 구현되지 않았으므로 Microsoft가이 의도를 역 추적했다고 가정하는 것이 안전하다고 생각합니다. 지금 변경하기에는 너무 늦었습니다. 웹에서 검색하여 이러한 계획으로 어떤 일이 발생했는지 알아 보려고했지만 답변을 찾을 수 없었습니다. 나는 아직도 그것의 바닥에 가고 싶었다.

그래서 Jeff Richter에게 이메일을 보냈고 직접 물어 봤습니다. 누군가 무슨 일이 있었는지 알면 그 사람이 될 것이라고 생각했습니다.

그는 12 시간 이내에 토요일 아침에 대답했으며 .NET 1.0 Beta 1 로더가 사용 가능한 최신 빌드 및 수정 어셈블리를 가져 오는이 '자동 롤 포워드'메커니즘을 구현했지만이 동작은 다음과 같습니다. .NET 1.0이 출시되기 전에 되돌 렸습니다. 나중에 이것을 되살리려 고했지만 CLR 2.0이 출시되기 전에는 만들지 않았습니다. 그런 다음 CLR 팀에 우선 순위를 둔 Silverlight가 등장하여이 기능이 더욱 지연되었습니다. 그 동안 CLR 1.0 베타 1 시절에 있었던 대부분의 사람들은 그 이후로 옮겨 왔기 때문에 이미 많은 노력을 기울 였음에도 불구하고 이것이 오늘의 빛을 볼 것 같지는 않습니다.

현재의 행동은 여기에있는 것 같습니다.

Jeff와의 논의에서 AssemblyFileVersion은 '자동 롤 포워드'메커니즘을 제거한 후에 만 ​​추가되었다는 점에 주목할 가치가 있습니다. 1.0 베타 1 이후에는 AssemblyVersion에 대한 모든 변경 사항이 고객에게 큰 변화가 있었기 때문에 빌드 번호를 안전하게 저장할 수있는 곳이 없습니다. AssemblyFileVersion은 CLR에서 자동으로 검사하지 않으므로 안전한 피난처입니다. 아마도 AssemblyVersion의 Major / Minor (breaking) 부분과 Build / Revision (non-breaking) 부분을 분리하려고 시도하기보다는 별도의 의미를 가진 두 개의 개별 버전 번호를 갖는 것이 더 명확 할 수 있습니다.

결론 : 당신이 당신을 바꿀 때 신중하게 생각하십시오 AssemblyVersion

다른 개발자가 참조 할 어셈블리를 제공 할 경우 해당 어셈블리의 AssemblyVersion을 변경할 때 (그리고 변경하지 않을 때) 매우주의해야한다는 것이 도덕입니다. AssemblyVersion을 변경하면 응용 프로그램 개발자는 새 버전에 대해 다시 컴파일하거나 (AssemblyRef 항목을 업데이트하기 위해) 어셈블리 바인딩 리디렉션을 사용하여 바인딩을 수동으로 재정의해야합니다.

  • 이전 버전과 호환되는 서비스 릴리스의 AssemblyVersion을 변경 하지 마십시오 .
  • 마십시오 당신이 주요 변경 내용을 가지고 알고 릴리스에 대한 AssemblyVersion을 변경합니다.

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")]

모든 흥미로운 서비스 정보를 포함하는 것은 AssemblyFileVersion이며 (현재 사용중인 서비스 팩을 알려주는이 버전의 개정 부분 임) AssemblyVersion은 오래된 2.0.0.0으로 고정되어 있습니다. AssemblyVersion을 변경하면 mscorlib.dll을 참조하는 모든 .NET 응용 프로그램이 새 버전에 대해 다시 컴파일되도록합니다.


9
좋은 대답입니다. 새로운 버전이 이전 버전과의 호환성을 위반하는 경우에만 AssemblyVersion을 변경하는 것이 가장 중요하다고 생각합니다 .
mwolfe02

1
반복적으로 나 자신에게 묻는 질문 중 하나는 언제 각 버전 번호를 변경해야 하는가하는 것입니다. AssemblyVersion의 글 머리표에 이것에 대한 명확한 설명이 추가되었으며 전체 답변이 흥미롭게 읽혔습니다.
RyanfaeScotland

이 세 가지의 기본 개념을 설명하는 많은 답변을보고 있습니다. 그러나 프로젝트 속성에서 편집 가능한 버전 번호와 어떤 관련이 있습니까? 어셈블리 정보 ...를 클릭하면 두 가지 버전을 변경할 수있는 옵션이 나타납니다. 어셈블리 버전을 변경하면 user.config가있는 폴더가 변경되고 파일 버전을 변경하면 exe 파일을 마우스 오른쪽 단추로 클릭하고 해당 속성으로 이동하면 표시되는 버전 번호가 변경됩니다. 그렇다면이 두 버전 번호는 AssemblyVersion, AssemblyFileVersion 및 AssemblyInformationalVersion에 어떻게 해당됩니까?
Kyle Delaney

처음에 작성한 블로그 게시물에 대한 링크는 404를 제공합니다. 새로운 위치가 있습니까?
Rob K

@RobK : 아, 사과드립니다. 해당 웹 사이트는 다운되었지만 블로그 게시물의 전체 내용이 답변에 재현되므로 아무것도 빠지지 않습니다. 깨진 링크를 제거하겠습니다.
Daniel Fortunov

43

AssemblyVersionAssemblyFileVersionWindows가 보는 동안 .NET 내부에 거의 머물러 있습니다. 디렉토리에있는 어셈블리의 속성으로 이동하여 버전 탭으로 전환하면 AssemblyFileVersion맨 위에 표시됩니다. 버전별로 파일을 정렬하면 탐색기에서 사용됩니다.

AssemblyInformationalVersion"제품 버전"에 매핑하고 순수 "인간이 사용하는"하기위한 것입니다.

AssemblyVersion확실히 가장 중요하지만, 나는 건너 뛰지 않을 것 AssemblyFileVersion입니다. 을 제공하지 않으면 AssemblyInformationalVersion컴파일러는 버전 번호의 "개정"부분을 제거하고 major.minor.build를 남겨두고 추가합니다.


23

AssemblyInformationalVersion그리고 AssemblyFileVersion이 파일의 속성을 확인하여 Windows 탐색기를 통해 파일에서 "버전"정보를 볼 때 표시됩니다. 이러한 속성은 실제로 VERSION_INFO컴파일러가 생성 한 리소스로 컴파일됩니다 .

AssemblyInformationalVersion"제품 버전"값입니다. AssemblyFileVersion"파일 버전"값입니다.

AssemblyVersion.NET 어셈블리에 고유 조립 로더 부하 / 바인딩 런타임에서 어셈블리의 버전을 알 수 있도록 .NET에 의해 사용된다.

이 중에서 .NET에 절대적으로 필요한 것은 AssemblyVersion속성 뿐입니다 . 불행히도, 특히 어셈블리 이름을 강하게 지정하는 경우 무차별 적으로 변경 될 때 가장 큰 문제를 일으킬 수 있습니다.


9

이 질문을 최신 상태로 유지하려면 AssemblyInformationalVersionNuGet에서 사용하고 시험판 접미사를 포함한 패키지 버전 을 반영하는 것이 좋습니다.

예를 들어 asp.net 코어 dotnet-cli와 함께 패키지 된 1.0.3. *의 AssemblyVersion

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

다음을 사용하여 리플렉션으로 검사 할 수있는 버전 1.0.3-ci-7의 패키지를 생성합니다.

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);

7

다른 것들에 주목할 가치가 있습니다.

1) 생성 된 어셈블리 파일의 Windows 탐색기 속성 대화 상자에 표시된 것처럼 "파일 버전"이라는 두 곳이 있습니다. 대화 상자의 헤더에 표시된 것은 AssemblyFileVersion이 아니라 AssemblyVersion을 보여줍니다.

기타 버전 정보 섹션에는 "파일 버전"이라는 다른 요소가 있습니다. 여기서 AssemblyFileVersion으로 입력 한 내용을 볼 수 있습니다.

2) AssemblyFileVersion은 일반 텍스트입니다. AssemblyVersion이 수행하는 번호 지정 체계 제한을 준수하지 않아도됩니다 (예 : <65K). 원하는 경우 3.2. <릴리스 태그 텍스트>. <datetime> 일 수 있습니다. 빌드 시스템은 토큰을 채워야합니다.

또한 AssemblyVersion이 와일드 카드 대체 대상이 아닙니다. AssemblyInfo.cs에 "3.0.1. *"값만 있으면 기타 버전 정보-> 파일 버전 요소에 표시됩니다.

3) 그래도 숫자 파일 버전 번호 이외의 것을 사용하는 설치 프로그램에 미치는 영향을 모르겠습니다.


2

어셈블리의 AssemblyVersion이 변경 될 때 강력한 이름을 가진 경우 참조 어셈블리를 다시 컴파일해야합니다. 그렇지 않으면 어셈블리가로드되지 않습니다! 강력한 이름이 없으면 프로젝트 파일에 명시 적으로 추가되지 않은 경우 빌드시 출력 디렉토리에 복사되지 않으므로 어셈블리에 따라, 특히 출력 디렉토리를 정리 한 후 누락 될 수 있습니다.


이것은 매우 흥미 롭습니다! "출력 디렉토리로 복사되지 않을 것"부분을 좀 더 자세히 설명해 주시겠습니까? 이 동작이 정의 된 위치에 대한 링크 일 수 있습니다. 왜 일부 간접 종속성이 때때로 복사되는지는 이해하지 못했지만 항상 그런 것은 아닙니다. 100 % 관련이어야합니다.
julealgon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.