.NET 4.0에 새로운 GAC가 있습니다. 왜 그렇습니까?


300

%windir%\Microsoft.NET\assembly\새로운 GAC 입니다. 이제 두 개의 GAC를 관리해야합니까 (하나는 .NET 2.0-3.5 응용 프로그램 용, 다른 하나는 .NET 4.0 응용 프로그램 용)?

문제는 왜?


7
질문을 해주셔서 감사합니다 .. 원래 위치에서 gac를 찾지 못하면 혼란 스러울 수 있습니다 :)
Jasl

2
좋은 질문입니다 ... 많은 감사합니다.
smwikipedia

1
질문에 +1 NET 4.0에서 개발을 시작했으며 "이중"GAC 문제로 혼동되었습니다.
Hernán

3
몇 번의 반복이 필요했지만 Microsoft는 마침내 DLL Hell을 .NET으로 가져 왔습니다. 예이!
아무것도 불필요

답변:


181

예. 2 개의 고유 한 GAC (Global Assembly Cache)가 있으므로 각각 개별적으로 관리해야합니다.

.NET Framework 4.0에서 GAC는 몇 가지 변경을 거쳤습니다. GAC는 각각의 CLR마다 하나씩 2 개로 분할되었다.

.NET Framework 2.0 및 .NET Framework 3.5 모두에 사용되는 CLR 버전은 CLR 2.0입니다. 이전 두 프레임 워크 릴리스에서는 GAC를 분할 할 필요가 없었습니다. Net Framework 4.0에서 이전 응용 프로그램을 손상시키는 문제.

CLR 2.0과 CLR 4.0 사이의 문제를 피하기 위해 GAC는 이제 각 런타임마다 개인 GAC로 분할됩니다. 주요 변경 사항은 이제 CLR v2.0 응용 프로그램이 GAC에서 CLR v4.0 어셈블리를 볼 수 없다는 것입니다.

출처

왜?

NET 4.0에서는 CLR이 변경되었지만 2.0에서 3.5는 변경되지 않았기 때문입니다. 1.1 ~ 2.0 CLR에서도 마찬가지입니다. GAC는 동일한 CLR에서 온다면 다른 버전의 어셈블리를 저장할 수있는 것으로 보입니다. 그들은 오래된 응용 프로그램을 중단하고 싶지 않습니다.

4.0의 GAC 변경 사항에 대해서는 MSDN 의 다음 정보를 참조하십시오 .

예를 들어 .NET 1.1과 .NET 2.0이 모두 동일한 GAC를 공유 한 경우이 공유 GAC에서 어셈블리를로드하는 .NET 1.1 응용 프로그램은 .NET 2.0 어셈블리를 가져 와서 .NET 1.1 응용 프로그램을 손상시킬 수 있습니다.

.NET Framework 2.0 및 .NET Framework 3.5 모두에 사용되는 CLR 버전은 CLR 2.0입니다. 그 결과 이전 두 프레임 워크 릴리스에서 GAC를 분할 할 필요가 없었습니다. CLR 4.0이 릴리스 된 Net Framework 4.0에서는 이전 (이 경우 .NET 2.0) 응용 프로그램을 깨뜨리는 문제가 다시 나타납니다. 따라서 CLR 2.0과 CLR 4.0 간의 간섭 문제를 피하기 위해 GAC는 이제 각 런타임마다 개인 GAC로 분할됩니다.

CLR이 이후 버전에서 업데이트됨에 따라 동일한 내용을 기대할 수 있습니다. 언어 만 변경되면 동일한 GAC를 사용할 수 있습니다.


18
이 블로그 게시물은 OP의 발견 내용 만 검토 하고 GAC를 분리해야하는 이유 는 설명하지 않습니다 . 원래 GAC가 4.0 어셈블리를 개별적으로 유지할 수 있었을 것입니다. 그들은 새로운 [AssemblyVersion]을 가지고 있습니다
Hans Passant

1
@Hans : 아마도 정확한 이유는 아니지만 "CLR 2.0과 CLR 4.0 사이의 문제를 피하기 위해"라는 질문도 있지만 그 안에는 두 가지 질문이 있습니다. 두 번째 질문은 "이제 두 개의 GAC를 관리해야한다는 것을 의미합니까? 하나는 .NET 2.0-3.5 앱용이고 다른 하나는 .NET 4.0 앱용입니까?"
Brian R. Bondy

2
"예를 들어, .NET 1.1과 .NET 2.0이 모두 동일한 GAC를 공유 한 경우이 공유 GAC에서 어셈블리를로드하는 .NET 1.1 응용 프로그램은 .NET 2.0 어셈블리를 얻을 수 있습니다. .NET 1.1 응용 프로그램을 손상시킵니다. "
Max Toro

67

나는 또한 왜이 GAC를 알고 싶어 다음과 같은 발견 마크 밀러 설명을코멘트 섹션.NET 4.0이이 전역 어셈블리 캐시 (GAC) :

마크 밀러는 말했다 ... 2010 년 6 월 28 일 오후 12:13

게시물 주셔서 감사합니다. "간섭 문제"는 의도적으로 모호했습니다. 글을 쓰는 시점에서 문제는 여전히 조사되고 있었지만 몇 가지 깨진 시나리오가 있음이 분명했습니다.

예를 들어 일부 응용 프로그램은 Assemby.LoadWithPartialName을 사용하여 가장 높은 버전의 어셈블리를로드합니다. 최고 버전이 v4로 컴파일 된 경우 v2 (3.0 또는 3.5) 앱이이를로드 할 수 없으며 작동했던 버전이 있어도 앱이 중단됩니다. 원래 GAC를 원래 위치에 분할했지만 Windows 업그레이드 시나리오에서 일부 문제가 발생했습니다. 이 두 가지 코드는 이미 배송 된 코드와 관련이 있으므로 버전 분할 된 GAC를 다른 곳으로 옮겼습니다.

이는 대부분의 응용 프로그램에 영향을 미치지 않으며 유지 관리 부담을 추가하지 않습니다. 두 위치 모두 기본 GAC API를 사용하여 액세스하거나 수정해야하며, 예상대로 파티션을 처리합니다. 이것이 나타나는 장소는 GetCachePath와 같은 GAC 경로를 노출하거나 관리 코드에로드 된 mscorlib 경로를 검사하는 API를 통해 이루어집니다.

v2를 출시 할 때와 어셈블리 ID의 일부로 아키텍처를 도입 할 때 GAC 위치를 수정했다는 점은 주목할 가치가 있습니다. 모두 여전히 % windir % \ assembly 아래에 있지만 GAC_MSIL, GAC_32 및 GAC_64를 추가했습니다. 안타깝게도이 릴리스에서는 옵션이 아니 었습니다.

미래 독자들에게 도움이 되길 바랍니다.


3
링크 된 기사에 대한 Miller의 의견은 해당 주제에 대한 내부자 의견을 제공합니다.
Nimesh Madhavan

66

원래 GAC는 이미 다양한 버전의 어셈블리를 저장할 수있었습니다. 그리고 프로그램이 실수로 잘못된 어셈블리를 참조한다고 가정 할 이유가 거의 없습니다. 모든 .NET 4 어셈블리에는 [AssemblyVersion]이 4.0.0.0까지 올라갔습니다. 새로운 공정 내 병행 기능이이를 변경해서는 안됩니다.

내 생각에 : 이미 "GAC에서 직접 참조하지 않는"규칙을 위반 한 .NET 프로젝트가 너무 많습니다. 이 사이트에서 여러 번 수행 된 것을 보았습니다.

프로젝트를 중단하지 않으려면 GAC를 옮기십시오. 역전은 Microsoft에서 성스러운 것입니다.


3
이것이 왜 그런지 를 설명하려는 유일한 대답입니다 . +1
Ed S.

1
@Hans Passant : "GAC에서 직접 참조하지 않는"규칙은 무엇을 의미합니까?
Max Toro

2
@Max : 컴퓨터에 두 개의 .NET 어셈블리 사본이 있습니다. c : \ windows \ microsoft.net 및 c : \ program files \ reference 어셈블리의 참조 어셈블리입니다. 그리고 런타임에 사용 된 것, GAC @ c : \ windows \ assembly. 그것들은 동일하지 않으며 64 비트가 예입니다. 마이크로 소프트는 쉘 확장 핸들러로 GAC를 참조하는 사람을 피하기 위해 최선을 다했다. 그리고 참조 추가 대화 상자. 100 % 효과적이지 않음
Hans Passant

@Hans Passant : 직접 참조는 'c : \ WINDOWS \ assembly \ GAC_MSIL \ System \ 2.0.0.0__b77a5c561934e089 \ System.dll'과 같습니다. 새 버전을 추가하면 해당 참조가 어떻게 깨지는 지 알 수 없습니다.
Max Toro

2
@Hans Passant : "그리고 프로그램이 실수로 잘못된 어셈블리를 참조한다고 가정 할 이유가 거의 없습니다" Assembly.LoadWithPartialNameGAC에 어셈블리의 2 가지 버전이있는 경우 어떻게됩니까?
Max Toro
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.