it-swarm-ko.tech

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

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


MSDN 메시지 :

  • AssemblyVersion :

    할당 된 어셈블리의 버전을 지정합니다.

  • AssemblyFileVersion :

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

  • AssemblyInformationalVersion :

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


이것은 후속 작업입니다 어셈블리 속성을 사용하는 가장 좋은 방법은 무엇입니까

824
Jakub Šturc

AssemblyVersion

어셈블리를 참조하는 다른 어셈블리가 보이는 위치. 이 번호가 변경되면 다른 어셈블리가 어셈블리에 대한 참조를 업데이트해야합니다! AssemblyVersion은 필수입니다.

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

[Assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

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

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

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

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

[Assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

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

코드 분석에서 이에 대해 불평 할 것입니다 (CA2243) - Microsoft (VS2013에서는 수정되지 않음)에보고됩니다.

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

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

[Assembly: AssemblyInformationalVersion("1.0 RC1")]
871

현재 어셈블리에서 버전을 지정하는 방법은 최소한 세 가지가 있으므로 .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 개별 어셈블리 의 빌드를 고유하게 식별하기위한 것입니다.

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

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

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

CLR은 AssemblyFileVersion을 신경 쓰지 않으며 검사도하지 않습니다.

AssemblyInformationalVersion은 전체 제품의 버전을 나타 내기위한 것입니다

AssemblyInformationalVersion은 제품 전체를 일관성있게 버전화할 수 있도록하기 위해 의도적으로 서로 다른 버전 관리 정책을 사용하여 독립적으로 버전을 지정하고 서로 다른 팀에서 개발할 수있는 많은 어셈블리로 구성 될 수 있습니다.

"예를 들어 제품의 버전 2.0에는 여러 어셈블리가 포함될 수 있습니다. 이 어셈블리 중 하나는 동일한 제품의 버전 1.0에 포함되지 않은 새로운 어셈블리이므로 버전 1.0으로 표시됩니다. 일반적으로이 버전 번호의 주요 부분과 중요하지 않은 부분을 설정하여 제품의 공용 버전을 나타냅니다. 그런 다음 전체 제품을 모든 어셈블리로 패키징 할 때마다 빌드 및 수정 부품을 늘립니다. "- Jeffrey Richter, [CLR via C # (Second Edition)] p. 57

CLR은 AssemblyInformationalVersion을 신경 쓰지 않으며 검토하지 않습니다.

AssemblyVersion은 CLR이 신경 쓸 수있는 유일한 버전이지만 (전체 AssemblyVersion에 대해 신경을 썼습니다)

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

이것은 매우 중요합니다. 왜냐하면 강하게 이름 붙여진 어셈블리를 참조 할 때 해당 어셈블리의 특정 AssemblyVersion에 단단히 묶여 있기 때문입니다. 전체 AssemblyVersion은 바인딩이 성공하기 위해 정확히 일치해야합니다. 예를 들어 빌드 타임에 강력한 이름의 어셈블리 버전 1.0.0.0을 참조하지만 런타임에 해당 어셈블리 버전 1.0.0.1 만 사용할 수있는 경우 바인딩이 실패합니다! (그런 다음 Assembly Binding Redirection .을 사용하여이 문제를 해결해야합니다.)

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.

나는이 혼란의 근원이 아마 마이크로 소프트가 원래 메이저 버전과 마이너 버전 부분에 대해서만 매칭함으로써 전체 AssemblyVersion의 엄격한 매칭에 조금 더 관대하기를 의도했기 때문이라고 생각한다.

"어셈블리를로드 할 때 CLR은 요청 된 어셈블리의 주/부 버전과 일치하는 최신 설치된 서비스 버전을 자동으로 찾습니다."- Jeffrey Richter, [CLR via C # (Second Edition)] p. 56

이것은 1.0 CLR의 Beta 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, [CLR via C # (Second Edition)] 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 (분리)와 Build/Revision (비 분리) 부분을 분리하려고 시도하는 대신 별도의 의미로 두 개의 개별 버전 번호를 갖는 것이 더 명확합니다.

최종선 : 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 응용 프로그램이 새 버전에 대해 다시 컴파일됩니다.

570
Daniel Fortunov

AssemblyVersion은 .NET 내부에 거의 머물러 있으며, AssemblyFileVersion은 Windows에서 볼 수 있습니다. 디렉토리에있는 어셈블리의 속성으로 이동하여 버전 탭으로 전환하면 AssemblyFileVersion이 맨 위에 표시됩니다. 버전별로 파일을 정렬하면 Explorer에서 사용하는 것입니다.

AssemblyInformationalVersion은 "제품 버전"에 매핑되며 순전히 "인간이 사용하는"것을 의미합니다.

AssemblyVersion은 분명 가장 중요하지만 AssemblyFileVersion을 건너 뛰지는 않습니다. AssemblyInformationalVersion을 제공하지 않으면 컴파일러는 버전 번호의 "수정"부분을 제거하고 major.minor.build를 남겨 두어 컴파일러를 추가합니다.

42
Bob King

AssemblyInformationalVersionAssemblyFileVersion은 파일 속성을보고 Windows 탐색기를 통해 파일의 "버전"정보를 볼 때 표시됩니다. 이러한 특성은 실제로 컴파일러에 의해 생성 된 VERSION_INFO 리소스로 컴파일됩니다.

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

AssemblyVersion은 .NET 어셈블리에만 해당되며 런타임시로드/바인딩 할 어셈블리 버전을 알기 위해 .NET 어셈블리 로더가 사용합니다.

이 중 .NET에서 절대적으로 필요로하는 것은 AssemblyVersion 특성뿐입니다. 불행히도 그것은 또한 무차별 적으로 변경 될 때 가장 큰 문제를 일으킬 수 있습니다.

21
Scott Dorman

이 질문을 최신으로 유지하려면 NuGet에서 AssemblyInformationalVersion을 사용하고 출시 전 접미어를 포함하여 패키지 버전 을 반영해야합니다.

예를 들어 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);
8
KCD

다른 것들을 주목할 가치가 있습니다 :

1) 생성 된 어셈블리 파일의 Windows 탐색기 속성 대화 상자에 표시된 것처럼 "파일 버전"이라는 두 개의 위치가 있습니다. 대화 상자의 머리글에 표시된 파일에는 AssemblyFileVersion이 아니라 AssemblyVersion이 표시됩니다.

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

2) AssemblyFileVersion은 일반 텍스트입니다. AssemblyVersion이하는 번호 지정 체계 제한 사항 (<build> <65K)을 준수 할 필요는 없습니다. 원하는 경우 3.2. <release tag text>. <datetime>이 될 수 있습니다. 빌드 시스템이 토큰을 채워야합니다.

또한 AssemblyVersion과 같은 와일드 카드 교체가 필요하지 않습니다. AssemblyInfo.cs에 "3.0.1. *"값만 있으면 다른 버전 정보 -> 파일 버전 요소에 정확히 표시됩니다.

3) 숫자 파일 버전 번호 이외의 것을 사용하는 설치 프로그램에 미치는 영향을 알지 못합니다.

7
DavidM

Assembly의 AssemblyVersion이 변경되면 강력한 이름이 있으면 참조하는 어셈블리를 다시 컴파일해야합니다. 그렇지 않으면 어셈블리가로드되지 않습니다! 강력한 이름이없는 경우 프로젝트 파일에 명시 적으로 추가되지 않으면 빌드 할 때 출력 디렉토리에 복사되지 않으므로 특히 출력 디렉토리를 정리 한 후에 종속 어셈블리를 놓칠 수 있습니다.

2
linquize