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

StackOverflow https://stackoverflow.com/questions/64602

  •  09-06-2019
  •  | 
  •  

문제

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


MSDN은 다음과 같이 말합니다.

  • 어셈블리 버전:

    특성을 나타내는 어셈블리 버전을 지정합니다.

  • 어셈블리파일버전:

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

  • 어셈블리 정보 버전:

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


이는 후속 조치입니다. 어셈블리 속성 사용에 대한 모범 사례는 무엇입니까?

도움이 되었습니까?

해결책

어셈블리 버전

어셈블리를 참조하는 다른 어셈블리가 표시되는 위치입니다.이 숫자가 변경되면 다른 어셈블리에서 해당 어셈블리에 대한 참조를 업데이트해야 합니다!그만큼 AssemblyVersion 필요합니다.

나는 다음 형식을 사용합니다. 메이저.마이너.결과는 다음과 같습니다.

[assembly: AssemblyVersion("1.0")]

어셈블리파일버전

배포에 사용됩니다.배포할 때마다 이 숫자를 늘릴 수 있습니다.설치 프로그램에서 사용됩니다.동일한 어셈블리를 표시하는 데 사용합니다. AssemblyVersion, 이지만 다른 빌드에서 생성됩니다.

Windows에서는 파일 속성에서 확인할 수 있습니다.

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

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

[assembly: AssemblyFileVersion("1.0.3100.1242")]

어셈블리 정보 버전

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

코드 분석에서는 이에 대해 불평합니다(CA2243). 마이크로소프트에 보고됨 (VS2013에서는 수정되지 않았습니다).

그만큼 AssemblyInformationalVersion 선택 사항입니다.지정되지 않으면 AssemblyFileVersion이 사용됩니다.

나는 다음 형식을 사용합니다. major.minor [문자열로 개정].결과는 다음과 같습니다.

[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, [C#을 통해 CLR (두 번째 판)] p.57

CLR은 AssemblyInformationalVersion에 관심을 가지거나 검사하지 않습니다.

그만큼 AssemblyVersion CLR이 관심을 갖는 유일한 버전입니다(그러나 전체 버전에 관심이 있습니다). AssemblyVersion)

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

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

전체인지에 대한 혼란 AssemblyVersion 일치해야 합니다.(예, 그렇습니다.)

어셈블리를 로드하려면 전체 AssemblyVersion이 정확히 일치해야 하는지 여부에 대해 약간의 혼란이 있습니다.일부 사람들은 바인딩이 성공하려면 AssemblyVersion의 주요 부분과 부 부분만 일치해야 한다는 잘못된 믿음을 갖고 있습니다.이는 합리적인 가정이지만 궁극적으로 잘못된 가정이며(.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가 원래 전체 AssemblyVersion의 엄격한 일치에 대해 주 버전 부분과 부 버전 부분에서만 일치하도록 의도했기 때문일 것입니다.

"어셈블리를로드 할 때 CLR은 요청중인 어셈블리의 주요/마이너 버전과 일치하는 최신 설치된 서비스 버전을 자동으로 찾습니다." - Jeffrey Richter, [C#을 통해 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#을 통해 CLR (두 번째 판)] p.164 (강조 광산)

이 변경 사항은 아직 구현되지 않았으므로 Microsoft가 이 의도를 역추적했다고 가정하는 것이 안전하며 지금 이를 변경하기에는 너무 늦었을 것입니다.나는 이 계획에 무슨 일이 일어났는지 알아보기 위해 웹을 검색해 보았지만 아무런 답도 찾을 수 없었습니다.나는 아직도 그것의 바닥에 도달하고 싶었습니다.

그래서 나는 Jeff Richter에게 이메일을 보내 그에게 직접 물었습니다. 무슨 일이 일어났는지 아는 사람이 있다면 그 사람일 것이라고 생각했습니다.

그는 토요일 아침에 12시간 이내에 응답했으며 .NET 1.0 베타 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 애플리케이션이 새 버전에 대해 다시 컴파일됩니다.

AssemblyVersion 거의 .NET 내부에 남아 있지만 AssemblyFileVersion Windows가 보는 것입니다.디렉터리에 있는 어셈블리 속성으로 이동하여 버전 탭으로 전환하면 AssemblyFileVersion 위쪽에 보이는 것이 바로 이것입니다.파일을 버전별로 정렬하면 Explorer에서 사용됩니다.

그만큼 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와 함께 패키지된 AssemblyVersion 1.0.3.*

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이 수행하는 번호 매기기 체계 제한 사항(예: <build> < 65K)을 따를 필요는 없습니다.원하는 경우 3.2.<릴리스 태그 텍스트>.<datetime>일 수 있습니다.빌드 시스템에서 토큰을 채워야 합니다.

또한 AssemblyVersion과 같은 와일드카드 대체가 적용되지 않습니다.AssemblyInfo.cs에 "3.0.1.*" 값이 있는 경우 이는 정확히 기타 버전 정보->파일 버전 요소에 표시됩니다.

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

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top