2012-08-01 2 views
2

우리는 COM 구성 요소 프로젝트와 COM 구성 요소를 등록하는 하나의 Windows 설치 프로젝트를 가지고 있습니다. 설치 프로젝트의 이전 빌드를 확인한 결과 COM 프로젝트의 클래스에 대해 생성 된 CLSID가 항상 변경되지만 해당 클래스에는 변경 사항이없는 것으로 보입니다. 이것은 같은 머신에서 서로 다른 버전의 구현을 유지하기를 원하기 때문에 우리가 원하는 방식입니다. 그러나이 프로젝트를 수동으로 빌드하고 regasm.exe를/regfile 옵션과 함께 여러 번 같은 날에 실행할 때 생성 된 reg 파일의 CLSID는 항상 동일합니다. 그것은 그들이 변화 한 이전의 사례에서 생각합니다, 그것은 그들이 다른 날에 지어 졌기 때문입니다, 그러나 나는 확실하지 않습니다. 그래서이 CLSID 자동 생성의 (기본) 규칙은 누구에게 말해 줄 수 있습니까? 우리가 프로젝트의 기본 설정을 사용하고 있다고 생각합니다.CLSID 자동 생성의 기본 규칙은 무엇입니까?

어셈블리 버전이 결과에 영향을 미치는지 확실하지 않습니다. 그러나 어셈블리 버전 번호를 Major.Minor. *로 지정합니다. 즉, 세 번째 숫자 (빌드 번호)는 1.1.2000 이후의 일이며 네 번째 숫자 (개정 번호)는 자정 이후 두 초로 나눈 값입니다. 클래스 코드가 변경되지 않아도 CLSID가 변경되는 경우 주 번호와 보조 번호가 동일합니다. 따라서 버전 번호가 CLSID에 영향을 주면 메이저 번호와 마이너 번호를 고려하지 않을 것입니다.

물론 우리는 이러한 클래스에 정적 GUID를 할당하지 않았습니다. 그렇지 않으면 설치 프로젝트에서 변경되지 않습니다.

도움 주셔서 감사합니다.

답변

2

[예 :] 속성을 명시 적으로 사용하지 않으면 인터페이스 및 클래스에 대한 guid가 자동으로 생성됩니다. 잘 수행 할 수 있습니다. 어셈블리 및 클래스 선언의 모든 부분이 포함되어 코드 바이너리가 이전 버전과 호환되지 않을 수 있습니다. COM에서 매우 중요한 이러한 비 호환성은 진단하기가 매우 어려울 수 있습니다.

알고리즘은 완전히 지정된 유형 이름과 유형의 메소드 및 필드의 선언을 사용합니다. 그것들을 문자열로 변환하고 ("선언을 문자열로 변환") 결과 문자열을 해쉬함으로써 guid로 변환합니다. "전체 지정 유형 이름"은 [AssemblyVersion]을 포함하여 여기에 천적입니다. 어셈블리 버전을 증가시키는 것이 어셈블리를 사용하는 코드와 호환되지 않는 Big Deal 인 경우 코드입니다. 이러한 코드는 다시 컴파일해야합니다. COM 클라이언트도 예외는 아닙니다.

앞에서 설명한 것처럼 [Guid] 특성을 직접 지정하여 CLSID를 특정 값으로 강제 설정할 수 있습니다. DLL 지옥을 잘못 가져 와서 변경 사항을 적용하지만 클라이언트 코드를 다시 컴파일하지 않을 경우 DLL 지옥을 호출 할 위험이 있습니다. 실패 모드는 불쾌한, 꽤 무작위적인 AccessViolation 예외이거나 잘못된 메서드 호출입니다. ComInterfaceType.IsIDispatch로 돌아 가면 클라이언트 코드가 런타임에 바인딩을 사용해야하므로 그렇게해야합니다. 또는 철 주먹으로 빌드 및 배포 프로세스를 제어하십시오.

+0

감사합니다. 한스, 매우 도움이됩니다. 우리는 CLSID를 빌드간에 서로 다르게 유지하려고합니다. 그리고 현재 그들이 변경되지 않을 이유는 어셈블리 버전 번호 생성에 약간의 문제가있는 것 같습니다. 앞에서 언급했듯이 세 번째와 네 번째 숫자는 빌드 날짜와 시간에 따라 달라 지지만 어떤 이유로 CLSID가 동일하게 유지되는 이유는 동일합니다. – tete

+0

[AssemblyFileVersion]을 [ 그렇지 않으면 큰 변화가 있습니다. –

+0

빌드 시간에 따라 빌드 및 개정 번호를 자동으로 변경하는 것은 바람직하지 않습니다 (실제 코드를 변경하지 않았더라도)는 바람직하지 않습니까? 그 일의 해가되는 것이 무엇입니까? 나는 그것이 게으른 환경이라고 생각한다. 배포 시나리오에서는 COM dll 및 기타 구성 요소를 설치 폴더에 설치합니다. 따라서 두 버전이 같은 컴퓨터에 설치되어있는 경우 서로 다른 폴더에 레지스트리에 두 개의 CLSID가 있어야하며 각각 궁극적으로 자체 폴더에있는 COM DLL을 참조합니다.이 폴더의 실행 파일 만 COM을 사용합니다. 이 경우에 문제가 보이십니까? – tete

관련 문제