[.net] AssemblyVersion, AssemblyFileVersion 및 AssemblyInformationalVersion의 차이점은 무엇입니까?
세 가지 어셈블리 버전 속성이 있습니다. 차이점은 무엇입니까? 내가 사용하면 괜찮습니까?AssemblyVersion
나머지를 하고 무시해도 습니까?
MSDN의 말 :
-
조립 버전 :
기여할 어셈블리의 버전을 지정합니다.
-
Win32 파일 버전 리소스에 특정 버전 번호를 사용하도록 컴파일러에 지시합니다. Win32 파일 버전은 어셈블리의 버전 번호와 같을 필요는 없습니다.
-
AssemblyInformationalVersion :
어셈블리 매니페스트에 대한 추가 버전 정보를 정의합니다.
답변
조립 버전
어셈블리를 참조하는 다른 어셈블리가 표시되는 위치 이 수가 변경되면 다른 어셈블리는 어셈블리에 대한 참조를 업데이트해야합니다! 이전 버전과 호환되지 않는 경우에만이 버전을 업데이트하십시오. 이 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")]
답변
.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 응용 프로그램이 새 버전에 대해 다시 컴파일되도록합니다.
답변
AssemblyVersion
AssemblyFileVersion
Windows가 보는 동안 .NET 내부에 거의 머물러 있습니다. 디렉토리에있는 어셈블리의 속성으로 이동하여 버전 탭으로 전환하면 AssemblyFileVersion
맨 위에 표시됩니다. 버전별로 파일을 정렬하면 탐색기에서 사용됩니다.
는 AssemblyInformationalVersion
“제품 버전”에 매핑하고 순수 “인간이 사용하는”하기위한 것입니다.
AssemblyVersion
확실히 가장 중요하지만, 나는 건너 뛰지 않을 것 AssemblyFileVersion
입니다. 을 제공하지 않으면 AssemblyInformationalVersion
컴파일러는 버전 번호의 “개정”부분을 제거하고 major.minor.build를 남겨두고 추가합니다.
답변
AssemblyInformationalVersion
그리고 AssemblyFileVersion
이 파일의 속성을 확인하여 Windows 탐색기를 통해 파일에서 “버전”정보를 볼 때 표시됩니다. 이러한 속성은 실제로 VERSION_INFO
컴파일러가 생성 한 리소스로 컴파일됩니다 .
AssemblyInformationalVersion
“제품 버전”값입니다. AssemblyFileVersion
“파일 버전”값입니다.
는 AssemblyVersion
.NET 어셈블리에 고유 조립 로더 부하 / 바인딩 런타임에서 어셈블리의 버전을 알 수 있도록 .NET에 의해 사용된다.
이 중에서 .NET에 절대적으로 필요한 것은 AssemblyVersion
속성 뿐입니다 . 불행히도, 특히 어셈블리 이름을 강하게 지정하는 경우 무차별 적으로 변경 될 때 가장 큰 문제를 일으킬 수 있습니다.
답변
이 질문을 최신 상태로 유지하려면 AssemblyInformationalVersion
NuGet에서 사용하고 시험판 접미사를 포함한 패키지 버전 을 반영하는 것이 좋습니다.
예를 들어 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);
답변
다른 것들에 주목할 가치가 있습니다.
1) 생성 된 어셈블리 파일의 Windows 탐색기 속성 대화 상자에 표시된 것처럼 “파일 버전”이라는 두 곳이 있습니다. 대화 상자의 헤더에 표시된 것은 AssemblyFileVersion이 아니라 AssemblyVersion을 보여줍니다.
기타 버전 정보 섹션에는 “파일 버전”이라는 다른 요소가 있습니다. 여기서 AssemblyFileVersion으로 입력 한 내용을 볼 수 있습니다.
2) AssemblyFileVersion은 일반 텍스트입니다. AssemblyVersion이 수행하는 번호 지정 체계 제한을 준수하지 않아도됩니다 (예 : <65K). 원하는 경우 3.2. <릴리스 태그 텍스트>. <datetime> 일 수 있습니다. 빌드 시스템은 토큰을 채워야합니다.
또한 AssemblyVersion이 와일드 카드 대체 대상이 아닙니다. AssemblyInfo.cs에 “3.0.1. *”값만 있으면 기타 버전 정보-> 파일 버전 요소에 표시됩니다.
3) 그래도 숫자 파일 버전 번호 이외의 것을 사용하는 설치 프로그램에 미치는 영향을 모르겠습니다.
답변
어셈블리의 AssemblyVersion이 변경 될 때 강력한 이름을 가진 경우 참조 어셈블리를 다시 컴파일해야합니다. 그렇지 않으면 어셈블리가로드되지 않습니다! 강력한 이름이 없으면 프로젝트 파일에 명시 적으로 추가되지 않은 경우 빌드시 출력 디렉토리에 복사되지 않으므로 어셈블리에 따라, 특히 출력 디렉토리를 정리 한 후 누락 될 수 있습니다.