RegFreeCOM : 등록(regsvr32)이 필요없도록 COM 참조하기

원문 : http://msdn.microsoft.com/msdnmag/issues/05/04/RegFreeCOM/

닷넷 개발환경에서 개발을 하더라도 항상 managed 코드나 어셈블리만을 다루는 것은 아니다.

아직까지 COM에 대한 의존도를 무시할 수 없다. 더군다나 우리가 꼭 사용해야 하는 윈도우/오피스 관련 컴포넌트들은 거의 COM 기반 인 경우가 많다. 이들을 가지고 개발을 하기 위해서 우리는 Interop 과정을 통해 interop.*.dll 과 같이 COM을 닷넷 환경에서 사용할 수 있도록 wrapping한 모듈을 생성해서 이를 참조 사용한다. (MS에서는 주요 COM 컴포넌트에 대해서는 PIA라고 해서 개발자들을 위해 미리 Interop 된 어셈블리를 제공하기도 한다.)
물론 우리의 고마운 Visual Studio는 이 작업을 대신 해 주므로 우리는 그냥 참조 추가만 해 주면 된다.
요컨대 아직 우리의 닷넷 기반 개발은 COM을 사용해야 할 때가 많다는 것이고, 그렇다면 우리가 이전에 “DLL Hell”이라 부르던 문제(?)에 대해 아직 완전하게 자유로울 수 없다는 이야기 되겠다. 그렇다면 닷넷 어셈블리처럼 자기 완결적인 정보를 스스로 가지고 있어서 XCOPY 만으로 배포가 가능한 그러한 COM을 만들 수는 없을까? 그러면 DLL Hell을 피하면서 맘 푹 놓고 COM을 참조해 개발을 하고, 클라이언트에 배포할 수 있을 텐데…
우연히 발견한 msdn 매거진의 아티클 하나가 참으로 가려운 곳을 긁어 주었다. 또한 이 기술인 이미 Windows XP와 함께 소개되었다는 사실은 나에게 한 소리한다. “너…시..공부 안할래?.... 남들 다 아는 사실을 니만 모르고 있다..무슨 노다지라도 캔 양…”, “알았다… 지금이라도 알았으니까 모른척 알고 있었던 척 하면 데잖아……-_-!”.

이 내용을 아시는 분은 그저 썩소 한방씩 보내기 바란다…..이번 글은 번역 수준으로 글을 올린다.
naive assembly 부분은 역자의 소질이 미약하여 번역이 어색할 것이다. 이해 바란다.

우리가 VB6나 ATL을 이용해 작성한 사용자컨트롤이나 또는 다른 객체를 작성하는 것은 COM을 이용하는 것이다. 닷넷 이전에 COM은 윈도우 상의 어플리케이션들을 위한 기본적인 컴포넌트 모델이었다.

그러나 COM 컴포넌트를 배포하는 것은 그것을 개발하는 것보다 힘이 들때가 많았다. COM 컴포넌트들은 머신내의 모든 어플리케이션들이 사용할 수 잇도록 전역적으로 등록되어진다. 불행히도, 이 전역적인 등록은 아주 주의 깊게 관리되지 않으면 이들을 사용하는 어플리케이션에 원치않는 부작용을 야기시키게 된다. 이러한 부작용을 우리는 DLL Hell이라 부른다.

이러한 요소들은 닷넷 환경에서 문제가 되지 않는다. 왜냐하면 컴포넌트는 등록되어질 필요가 없으며, 어플리케이션에 분리된 형태로 존재하고, 또한 GAC에 도움으로 잘 정의된 side-by-side 방식에 의해 관리되어 지기 때문이다.

다양한 마이그레이션 마법사는 우리의 코드를 닷넷 프레임웍로 변환하게끔 도와줄 수 있지만, 반드시 실행되는 것은 아니다.

윈도우 XP는 registration-free COM(Reg-Free COM) 이라 부르는 COM 액티베이션 모델을 소개한다. Ref-Free COM은 COM 컴포넌트를 위한 레지스트리에 대한 대안으로서 등장했다. 이는 일반적으로 레지스트리에 설치되는 모든 표준 컴포넌트 등록 정보를 파일로서 표현하도록 한다. 그리고 이 파일은 어플리케이션과 동일한 폴더에 저장되어 진다.

이 문서는 VS2005의 새로운 Reg-Free COM 지원 기능을 이용해서 기존 COM 컴포넌트를 이용하는 어플리케이션을 어떻게 배포하는지 보여줄 것이다. 이 기능은 우리가 XCOPY나 ClickOnce와 같은 간단한 배포 모델로서 이러한 어플리케이션을 배포할 수 있도록 해준다.

Reg-Free COM Overview

전통적으로, 어플리케이션이 COM을 사용하는 경우, 컴포넌트는 작동되기 위핸 등록되어져야만 한다. Figure 1에 보여지는 것 처럼.
이는 어플리케이션이 네이티브 코드이거나 또는 닷넷 프레임웍 기반이냐에 상관 없이 적용되는 규칙이다.

Figure 1 Traditional COM Activation

Figure 1 Traditional COM Activation

시스템 레지스트리에 컴포넌트 정보를 등록하는 것의 이점은 여러 어플리케이션에 의해 공유되어 질 수 있다는 것이다. 또한 컴포넌트를 네트웍의 다른 컴퓨터 상에 설치하고 이를 활성화 하는 것 역시 가능하다. 만일 우리의 어플리케이션이 이러한 기능이 전혀 필요없다면, 즉 오로지 특정 어플리케이션 만이 해당 컴포넌트를 사용하는 상황이라면, 이 머신에 대해 적역적으로 등록하는(시스템 레지스트리에 등록하는) 과정 자체는 불필요한 부담이 된다.

먼저, 모든 컴포넌트가 적절하게 등록되었음을 확인하는 것은 대게 별도의 MSI 또는 EXE 인스톨러와 같은 셋업 프로그램이 필요하다는 것을 의미하게 된다. 또한, 컴포넌트 등록은 12개에서 수천개 까지 방대한 양의 레지스트리 키를 등록시킬수 있다. 만일 이중의 하나라도 잘못되면, 어플리케이션은 작동을 하지 않는다. 이런식으로 등록정보가 머신에 산재하게 된다면 설치제거나 업데이트를 매우 어렵게 한다. 특히나 컴포넌트가 여러 어플리케이션에 의해 공유된다면 더욱 그럴것이다.

Ref-Free COM은 전통적인 COM과는 달리, 시스템 레지스트리에 별도로 컴포넌트가 등록될 필요가 없다. 따라서 이전에 언급된 문제들을 피할 수 있다. 이는 모든 정보를 시스템 레지스트리가 아닌 XML manifest에 표현한다. 이 XML은 단지 어플리케이션 폴더 상에 존재하는 하나의 파일일 뿐이다.

컴포넌트가 manifest를 가지고 있다면, 컴포넌트의 Activation 과정에서 운영체제는 레지스트리를 보기 전에 먼저 manifest를 보게 된다.

Figure 2 Isolated COM Activation

Figure 2 Isolated COM Activation

Reg-Free COM 컴포넌트 모델을 활성화하기 위해서 프로그램(WindowsApplication1.exe)의 일부로서 어플리케이션 manifest(WindowsApplication1.exe.manifest)가 존재하기만 하면 된다.

이는 프로그램이 실행될 때 마다, Native Assembly Loader는 실행파일의 이름에 기반한 manifest 파일을 찾기 때문에 가능하다.

닷넷 어셈블리를 위한 컴포넌트 모델과 같이, 어플리케이션 폴더 외부에 다른 별도의 추가 정보가 존재할 필요가 없다. 윈도우는 컴포넌트 파일과 일치하는 각 식별자(CLSID)에 맵핑 정보 테이블을 내부적으로 구축한다. 이는 어플리케이션 코드가 실행되기 전인, CreateProcess 과정에서 수행된다. 그 후에, 어플리케이션이 컴포넌트를 인스턴스화(메모리내에 객체로서 생성) 할때 CoCreateInstance는 는 시스템 레지스트리를 보기 전에 이 내부의 맵핑 테이블을 먼저 보게 된다. 만일 모든 컴포넌트가 하나 또는 그 이상의 manifest에 의해 완전하게 표현되어 있다면, 어떠한 컴포넌트 등록도 필요치 않게 된다.!!

이 모델의 주요한 이점은 COM 컴포넌트가 완전하게 어플리케이션으로부터 분리되어 진다는 것이다. 다른 어플리케이션이 동일한 COM 컴포넌트( 혹은 다른 버전의 동일 컴포넌트)가 등록되어 지기를 요구한다 할 지라도, 이 어플리케이션은 어떤 방식으로도 간섭을 받지 않는다. 다른 어플리케이션과 완전히 독립적으로 컴포넌트를 사용하게 되는 것이다.

그래서 다른 한편으로는 이 어플리케이션을 위한 COM 컴포넌트를 다른 어플리케이션이 접근할 수 있는 방법도 없다. 그러므로, 버전 충돌 이나 컴포넌트의 GUID 변경으로 인해 야기되는 문제들은 Reg-Free COM를 명시적으로 사용하므로써 피할 수 있게 되는 것이다. (그러나 이러한 점이 컴포넌트의 versioning 전략을 포함한 분배의 회피 수단으로서 사용될 수 없다 할지라도)

결국 업데이트와 설치제거는 어플리케이션 폴더를 제거하거나 대체하는 것이 가장 간단하다.

덧붙이면, Reg_Free COM의 이점을 얻기 위해 기존 코드를 수정할 필요는 없다.적합한 manifest 구성을 설정하는 것만으로 충분하다. 사실, Reg-Free COM의 원래 의도는 기존 VB6, C++ 과 같은 언어로 작성된 네이티브 어플리케이션을 위한 것이었다. 이 글은 닷넷 기반 어플리케이션에서 Reg-Free COM을 사용하는 것에 초점을 두고 있다.

언급했듯이 Native Assembly Loader가 COM 컴포넌트를 manifest를 이용해 바인딩하는데 실패하면, 이전 방식대로 시스템 레지스트리에서 컴포넌트 등록정보를 찾게 된다. 이러한 행동은 Reg-Free COM 어플리케이션으로 적절하게 구성되지 않은 어플리케이션도 작동될 수 있도록 한다. 그러므로, 어플리케이션이 Reg-Fress COM을 위해 올바르게 구성되었는지를 검증하기 이해서 Clean 머신에서 테스트를 하는 것이 가장 좋다.

Isolation COM Components

Visual Studio 2005는 간단한 스위치 기능으로서 COM 컴포넌트를 격리시키도록 하는 새로운 기능을 제공한다. 이는 컴포넌트의 Type Library와 등록 정보로부터 manifest를 자동으로 생성해 준다.

그래서, 개발자 머신 상에 해당 COM 컴포넌트가 등록되어 져야만 COM 컴포넌트를 격리시키는 것이 가능하다. 그러나 이러한 개발자 머신의 헌신 덕분에 우리는 엔드 유저의 머신 상에서 컴포넌트가 등록 과정을 제거할 수 있게 되는 것이다.

Visual Studio 2005 상에서 모든 COM 인터페이스는 Isolated 라 불리는 새로운 속성을 가지고 있다. 기본적으로, 이 속성은 false 값을 가진다. False 값은 이 컴포넌트는 정상적인, 등록된 COM 참조로 취급되어야 한다는 것을 의미한다. 즉 전통적인 COM 참조가 되겠다.

이 값이 True이면, 빌드 타임에 컴포넌트에 대한 manifest가 생성되게 한다. 이는 또한 해당하는 컴포넌트 파일이 어플리케이션 폴더로 복사되어 지게끔 한다. Manifest 생성기가 격리된 COM 참조를 발견하게 되면, 이는 컴포넌트의 Type Library의 모든 CoClass 항목을 열거하게 되고, 각 항목을 일치하는 등록 데이터와 연관시키게 된다. 이 과정 내에서, manifest 는 컴포넌트 파일내에 존재하는 모든 COM 클래스에 대한 정의를 자동으로 가지게 된다.

COM 컴포넌트를 격리하는 기능은 VB6.0 COM 컴포넌트를 VB.NET 또는 C# 어플리케이션 내에 Reg-Free COM으로 배포하기 위해 고안되었다. 이 기능은 VB6.0 컴포넌트에 국한되지 않는다. 그러나 Reg-Free COM의 한계가 존재한다. 이는 "The Limitations of Reg-Free COM" 를 참조 바란다.

다음의 두가지 시나리오에서 어떻게 작동하는지를 보여줄 것이다. 먼저 간단한 VB6.0으로 COM 컴포넌트를 생성하고, 이것이 어떻게 Reg-Free COM을 이용해 배포되는지를 보여줄 것이다. 그리고, 조금 더 복잡한 예제로서 ActiveX 컨트롤이 Reg-Free COM 하에서 어떻게 작동하는지를 볼 것이다.

Isolating a Simple COM Component

VB6.0으로 간단한 COM 컴포넌트를 만드는 것으로 시작한다.
VB6.0에서 ActiveX DLL 형태로 프로제트 생성하고 Class1 코드 모듈에 아래의 코드를 넣는다. 컴포넌트 이름은 VB6Hello로 한다.
VB6가 설치되지 않은 독자는 그냥 첨부된 VB6Hello.dll을 사용해도 된다.
컴파일 한 후 VB6Hello.dll 을 regsvr32로 등록한다.(개발자 머신에는 등록해야 한다.)

	Public Sub SayHello()    	MsgBox "Hello from Visual Basic 6.0"	End Sub

주의 할 점은 ActiveX DLL, ActiveX Control 프로젝트 형식만이 Reg-Free COM 을 지원한다. ActiveX EXE , ActiveX Document 프로젝트 타입은 지원하지 않는다. ("The Limitations of Reg-Free COM"에서 언급되어 진다.)

다음 단계로, 이 COM 컴포넌트를 닷네 윈 폼 어플리케이션에서 참조를 한다.
Visual Studio 2005를 시작하고, 새로운 “RegFreeComDemo_1” 라는 이름의 윈 폼 프로젝트를 생성한다.
“VB6Hello.dll” 에 대한 참조를 추가한다.
“Say Hello” 라는버튼을 추가한다. 버튼의 클릭 이벤트 핸들러에 아래의 코드를 넣어준다.

  	private void button1_Click(object sender, EventArgs e)	{		VB6Hello.Class1Class cls = new VB6Hello.Class1Class();		cls.SayHello();	}

F5를 눌러 실행을 하게 되면 아래의 그림과 같은 실행화면을 만날 수 있다.

Figure 3 RegFreeComDemo1

Figure 3 RegFreeComDemo_1

Reg-Free COM 부분으로 넘어가기 전에 몇가지 살펴보도록 한다.
먼저 빌드 과정에서 생성된 파일을 보면,

Interop.VB6Hello.dll, RegFreeComDemo_1.exe, RegFreeComDemo_1.exe.config 이렇게 존재한다.

여기서 Interop.VB6Hello.dll은 빌드과정에서 자동으로 생성된 COM Interop 어셈블리이다.
그러나 VB6Hello.dll은 폴더 내에 존재하지 않는다는 점을 주목한다.

COM 컴포넌트를 등록 해제 한다. (regsvr32 /u VBHello.dll)

그리고 다시 Visual Studio 2005 IDE 외부에서 RegFreeComDemo_1.exe를 실행한다.(실행파일을 그냥 실행) 그러면 버튼을 눌렀을 때 어플리케이션이 실패하는 것을 확인할 수 있다.

확인 했으면 다시 COM 컴포넌트를 등록( regsvr32) 한다.

이제 COM 컴포넌트를 격리해보자.(Reg-Free COM으로 만들어 보자)
참조 목록이 있는 Reference 노드에서 VB6Hello를 선택하고, Isolated 속성을 True로 변경한다.

다시 실행(F5) 하게되면 정상적으로 작동하게 된다. 이전과 별반 차이가 없이 보이지만 내부적으로 이는 현재 Reg-Free COM 하에서 작동을 하는 것이다.

이를 입증하기 위해, VB6Hello.dll을 다시 등록해제 한 후 Visual Studio 2005 개발환경 외부에서 (실행파일을 그냥 실행) RegFreeComDemo_1.exe를 다시 실행해 본다. 버튼을 클릭하면 잘 작동하는 것을 확인 할 수 있다.!!!!
(앞의 과정에서 regsvr32 /u VB6Hello.dll 한 후 실행 했을 때 오류가 났던 것과는 다르다.)

만일 임의로 manifest 파일의 이름을 다른 이름으로 변경하게 되면 다시 어플리케이션을 실패하게 된다.
빌드 과정에서 생성된 5개의 파일을 확인한다.

  • Interop.VB6Hello.dll,
  • RegFreeComDemo_1.exe,
  • RegFreeComDemo_1.exe. con fig,
  • RegFreeComDemo_1.exe.manifest,
  • VB6Hello.dll

마지막 두개의 파일 COM 컴포넌트를 격리(Isolated=True) 한 후 새롭게 나타난 파일이다.

어플리케이션 manifest 파일, RegFreeComDemo_1.exe.manifest가 바로 Reg-Free COM을 가능하게 하는 바로 그 manifest 파일이다. 위 파일들을 .NET Framework 2.0과 Windows XP가 설치된 다른 머신에 XCOPY 복사하여 실행하여도 잘 작동을 하게 된다.(어떠한 등록 과정(regsvr32) 없이도)
Windows XP는 VB 런타임 라이브러리를 포함하고 있으므로, MSVBVM60.dll, OLEAUT32.dll 등과 같은 라이브러리를 설치해야 할 필요는 없다.
(그러나 어떤 머신에서는 설치가 제거되었거나 어떤 이유에서든지 VB 런타임이 설치되지 않은 상황이 반드시 발생한다… 이럴 때는 MS 다운로드 사이트 가서 VB6 런타임 설치파일을 다운 받아서 설치해주어야 한다.)

어플리케이션 manifest는 실제로 XML 문서이다. 이 파일의 내용은 Figure 5에 있다.

Figure 5 Reg-Free COM Application Manifest

<?xml version="1.0" encoding="utf-8"?>

<assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<assemblyIdentity name="RegFreeCOMDemo_1.exe" version="1.0.0.0" type="win32" />

<file name="VB6Hello.dll" asmv2:size="20480">

<hash xmlns="urn:schemas-microsoft-com:asm.v2">

<dsig:Transforms>

<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />

</dsig:Transforms>

<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />

<dsig:DigestValue>by35ekL4xX8qNvjy6IdVbVYnv9Q=</dsig:DigestValue>

</hash>

<typelib tlbid="{479e93bd-102c-40c9-931f-4baad33b0bbb}" version="1.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />

<comClass clsid="{48245372-4586-436b-a715-8bfd07e742eb}" threadingModel="Apartment" tlbid="{479e93bd-102c-40c9-931f-4baad33b0bbb}" progid="VB6Hello.Class1" />

</file>
</assembly>


(Hash와 GUID 식별자는 다를 수 있다.)

<file> 요소를 보면 <comClass>, <typelib> 요소를 포함하고 있다. 보는 바와 같이 클래스와 Type Library의 GUID는 manifest에 선언되어 있다. 이는 전통적인 방식에서 시스템 레지스트리에 등록되는 정보와 동일한 정보이다.

ClickOnce를 사용해 본적이 있다면, ClickOnce 어플리케이션 manifest가 존재한다는 것을 알 수 있으며 이 파일이 곧 바로 위에서 말한 manifest 파일이다. 즉 이는 ClickOnce 와 RegFree COM 정의는 동일한 파일 내에 존재할 수 있다는 것을 의미 한다.
그럼 ClickOnce로 배포 되어 질 때 동일한 어플리케이션에 어떤 변화가 일어나는지 보도록 한다.
Visual Studio 2005 에서 프로젝트를 선택한 후 Publish 명령을 실행한다. 그러면 Publish 마법사가 뜬다. 여기서 ClickOnce 구성을 한다.
(ClickOnce에 대해서는 다른 문서 참조 바람)

* ClickOnce 배포를 하기 전에, VB6Hello를 등록해제 했다면, 다시 등록하기 바란다. 언급했듯이 개발자 머신에는 해당 COM 컴포넌트가 반드시 등록되어야 한다. 그렇지 않으면 컴파일이 실패한다.

ClickOnce로 배포를 통해 실행하더라도 잘 작동을 한다. 물론, 실행하는 클라이언트에서 VB6Hello.dll을 등록(regsvr32)한 적이 없다.그러면 ClickOnce의해 배포되어져 내려온 어셈블리를 확인하면, 당연히 아래와 같이 예상대로 어셈블리와 COM 컴포넌트가 존재할 것이다.

ClickOnce 버전의 manifest 파일은 이 문서의 첨부에 포함되어 있으며, 조금 확인해 보면,

이전과 동일하게 <file>, <comClass>, <typeLib>를 포함하지만, 전체 어플리케이션의 모든 파일에 대한 정의를 포함하고 있다. 추가적으로 어플리케이션의 무결성을 보증하기 위한 해시정보가 모든 파일과 어셈블리에 요구된다.

또한 ClickOnce 어플리케이션은 반드시 Sign이 필요하다 XCOPY로 배포하는 (이전의 것) 경우는 이러한 Sign이 필요치 않으며, 이들의 어플리케이션 보안은 Full Trust로 정의되어 진다. 네이티브 코드를 직접 참조하는 모든 어플리케이션(COM 컴포넌트를 포함한)은 Full Trust 보안 레벨로 정의된다. Visual Studio 2005는 만일 우리가 하나 이상의 COM 참조에 Partial trust를 이용하고 있는 경우, 빌드 시 경고를 표시하게 된다.

확인할 사실은 Manifest 내에는 ClickOnce 배포를 위한 정보와 우리가 하고 있는 RegFreeCOM을 위한 정보가 공존할 수 있고, 이 작업은 Visual Studio 2005에 의해 자동으로 이루어 진다는 것이다.

생뚱맞은 이야기지만, Reg-Free COM을 사용하는 경우 최소한의 요구되는 OS는 Windows XP이다.

이번 샘플은 Reg-Free COM을 이용해 간단한 컴포넌트를 호출하는 방법을 보았다. 이는 비즈니스 객체와 같은 훨씬 복잡한 컴포넌트에도 쉽게 적용할 수 있다.

A More Complex Example

이번 샘플에서는 미리 만들어 놓은 VB6ControlTest” 컴포넌트를 이용할 것이다. 이는 VB6 개발환경과 함께 설치되는다른 ActiveX 컨트롤을 사용하고 있는 VB6 사용자 컨트롤이다.

VB6ControlTest.ocx를 로컬 컴퓨터로 복사한 후 등록한다.

Visual Studio 2005를 시작하여 새로운 윈 폼 프로젝트를 생성하고 RegFreeComDemo_2로 이름을 정한다.

도구상자(toolbox)에 VB6ControlTest 컴포넌트를 추가한다.

VB6ControlTest 컴포넌트를 도구상자에서 윈 폼 위로 Drag & Drop으로 추가한다.

Figure 6 RegFreeComDemo2 Program

Figure 6RegFreeComDemo_2 Program

이제 ActiveX 컨트롤을 격리해 보자. 참조 노드에서 VB6ControlTest 항목과 AxVB6ControlTest 항목을 선택하고 Isolated 속성을 True로 변경한다.

우리는 사용자 컨트롤(VB6ControlTest)을 격리했다. 그러나 우리는 사용자 컨트롤에 의해 참조되는 컨트롤들도(VB6 개발환경과 함께 설치된 ActiveX 컨트롤들) 격리하고 싶다.

그렇게 하기 위해서 우리는 단지 이들 컨트롤들을 프로젝트에서 참조 추가하고 이들의 Isolated 속성을 True로 변경한다.

· Microsoft Common Dialog Control 6.0 (SP6)
· Microsoft Rich Textbox Control 6.0 (SP6)
· Microsoft Tabbed Dialog Control 6.0 (SP6)
· Microsoft Windows Common Controls 6.0 (SP6)
· Microsoft Windows Common Controls-2 6.0 (SP6)

주의할 점은 순수하게 UI 위젯 형태의 컨트롤들은 Reg-Free COM 하에서 대부분 잘 작동하지만 반드시 테스트 해 보아야 한다.

Publish 마법사를 통해 ClickOnce 게시를 한다. 그리고 .NET Framework 2.0만 설치된 다른 머신으로 가서 게시된 ClickOnce 어플리케이션을 설치/실행해 보면, ActiveX 컨트롤들이 자연스럽게 배포되어 지는 것을 확인할 수 있다.

격리시킨 OCX 들이 배포되어져 있다.

Native Assemblies

Isolated 속성은 기존 COM 컴포넌트를 정말 쉽게 격리시키고 배포할 수 있게 해 준다. 하지만 컴포넌트가 어떤 vender나 컴포넌트 소유자로부터 manifest와 함께 제공되어 졌다면, 우리는 native assembly를 직접 참조할 수 있다. 이 경우, 사실 컴포넌트 제작자에 의해 제공된 manifest를 이용하는 것이 훨씬 편하고 선호될 것이다.

Visual Studio 2005에서는 native assembly 에 대한 참조를 지원한다. native 참조는 참조하는 파일의 Type 속성이 native로 설정된 경우 생성된다. native 참조를 추가하기 위해 프로젝트에서 참조 추가를 하고 manifest의 위치로 이동한다. 어떤 컴포넌트는 DLL 내에 manifest를 포함시킨다. 이 경우, DLL 자체를 선택할 수 있으며, 그러면 Visual Studio는 해당 dll이 embedded manifest를 포함하고 잇다는 것을 감지하게 되면 이를 native 참조로 추가하게 된다.

native 어셈블리는 컴포넌트와 연관된 추가적인 파일들을 정의할 수 있다. 그리고 다른 독립적인 native 어셈블리들을 참조할 수 도 있다.
임의의 복잡한 native 어셈블리들과 파일들을 수동으로 생성 시킨 manifest 내에 임의로 캡슐화 하는 것도 가능하다.
Visual Stuido 2005는 참조하는 컴포넌트와 동일한 폴더에 존재하는 어떤 파일 또는 독립적인 native 어셈블리들을 자동으로 manifest에 포함시킬 것이다.
Manifest는 xml이므로 컴포넌트 제작자는 자신의 컴포넌트내에 native 어셈블리를 포함시키고 싶다면 manifest 파일을 수동으로 생성할 수도 있다.
Platform SDK에 포함된 MT 툴을 이용할수도 있다. 물론, VB.NET 또는 C# 클래스 라이브러리 내에서 native 참조와 Reg-Free COM을 사용할 수 있다.

흥미롭게도, 결과 컴포넌트는 managed 어셈블리(.dll)와 native 어셈블리(.manifest) 두 개로 이루어 진다. 다른 프로젝트에서 이 컴포넌틀 참조할 때, 두 참조를 모두 추가해야만 컴포넌트를 제대로 사용할 수 있다. 프로젝트 참조를 사용할 때, 두 어셈블리는 자동으로 참조되어 진다. 프로젝트 참조 형태로 추가하지 않으면, 참조 추가를 두 번 해주어야 한다. 참조는 DLL에 대한 참조 한번과 manifest에 대한 참조, 이렇게 두 번의 작업이 필요하다.

위의 이야기는 조금은 어려운 감이 있지만, 요지는 우리가 *.manifest 파일을 참조로 추가할 수 있어 그 manifest 내에 포함된 native 어셈블리들을 참조로 추가할 수 있다는 것이다.
간단한 테스트를 위해 NativeTestClient.dll을 참조 추가하고, 이 COM 컴포넌트 제작자가 배포한 NativeTestClient.dll.manifest 파일을 참조 추가해 본다. 이 manifest 내에서는 해당 컴포넌트 제작자가 자신의 컴포넌트 내에서 참조하는 다른 native 어셈블리(NativeCOM.dll)에 대한 참조 정보가 있을 것이다.(아래의 예에서 NativeTestClient.dll 과 NativeTestClient.dll.manifest, NativeCOM.dll은 모두 동일한 폴더 내에 존재해야 한다.)

아래처럼 NativeTestClient.dll.manifest 파일에 포함된 native assembly 에 대한 참조 정보로 인해 NativeCOM.dll이 자동으로 추가되었음을 확인할 수 있다.

Conclusion

Reg-Free COM 은 COM 컴포넌트를 사용하는 어플리케이션 배포에 있어 어려웠던 점을 해소하는 훌륭한 방법이다. 이는 ActiveX 컨트롤에 대해 작동을 한다. 그러나 이는 UI가 없는 비즈니스 객체에 대해서도 작동을 한다. 이는 native 와 COM 컴포넌트를 어플리케이션 격리와 배포의 용이성 측면에서 manged 컴포넌트 수준으로 향상시키는 기술이라 할 수 있다.
유일한 주요 결점은 최소한의 플랫폼으로서 Windows XP가 필요하다는 점이다.
그러나 데스크탑 환경이 날로 향상되는 환경에서 이 새로운 기술이 제공하는 이점은 이러한 제약을 충분히 극복하고 있다고 여겨진다.



첨부파일 : RegFreeCOM.zip (1614Kbytes)

+ Recent posts