ClickOnce, 사용자 정의 필수 구성 요소 포함하기

배경

ClickOnce는 닷넷 프레임웤 2.0에서 추가된 새로운 어플리케이션 배포방법입니다. 닷넷 프레임워크 1.X 버전에서 지원했던 NTD(No touch deployment)나 Windows Installer 방식에 더해(2.0에서도 여전히 지원합니다.) 두 배포방식의 장점을 취합하고 단점을 보완하여 소개한 것이 ClickOnce입니다. 하지만 여전히 NTD와 Windows Installer가 필요한 이유는 ClickOnce가 다른 두 개의 배포방식을 대체하는데 목적이 있는 것이 아니기 때문입니다. NTD는 Sandbox 내에서 배포되고 수행되는 어플리케이션을 위한 것이기 때문에(Smart Client Application) 강력한 보안을 지원하는 대신 많은 제약이 뒤따릅니다. 예를 들면 부트스트래퍼 미지원, GAC에 공용어셈블리 설치 불가, 설치위치 임의 변경 등이 되겠네요. 또한 NTD의 고질적인, 달리 말해 많은 개발자가 고민하는 문제가 보안설정변경(CAS – Code Access Security)이겠죠. CAS 변경을 위해 별도의 ActiveX에 의존하게 됩니다. 또한 클라이언트 머신에 닷넷 프레임워크가 설치되어 있어야 하는데 NTD는 부트스트래퍼를 지원하지 않으므로 닷넷 프레임워크를 설치과정에 포함시킬 수가 없죠. 반면에 Windows Installer는 굉장히 강력하죠. 자동업데이트 및 온라인실행 지원이 되지 않는 것을 제외하곤 상상가능한 모든 설치작업이 가능합니다. 그렇다면 ClickOnce는? 앞에서 거론한 NTD의 대표적인 단점인 부트스래퍼와 CAS 변경 자동화 기능을 지원하며 Windows Installer의 단점인 자동업데이트와 온라인/오프라인 실행 및 설치를 지원합니다. 물론 단점도 있죠. 이 문서에서 다루려는 내용도 ClickOnce의 단점 중에 하나를 보완하기 위한 방법을 알리기 위한 것입니다. 단점이라기 보다는 까다로운 점이라고 하는 게 정확할 듯 합니다. 구현 가능한 것이니까요.

주제

이 문서의 주제는 ClickOnce에 사용자 정의 필수 구성요소 추가하는 방법에 대한 것입니다.

사전지식

ClickOnce는 별도의 설정을 하지 않는 이상 어플리케이션이 참조하는 공용어셈블리에 대해 설치작업을 지원하지 않습니다. 즉, A라는 어플리케이션이 Ref.A라는 공용어셈블리(여기에서 언급하는 공용어셈블리는 써드파티 제품을 의미합니다. 즉, 로컬어셈블리로 변환 불가한 어셈블리입니다. – 추1 : 개발자가 생성한 공용어셈블리 배포에 대해서는 테스트가 필요합니다.)를 참조하는 프로젝트를 게시할 경우 Ref.A는 기본설정에 배포될 응용프로그램 파일리스트에서 제외됩니다. 임의로 포함되도록 변경하더라도 설치과정에서 오류가 발생합니다. (대표적인 것으로 Microsoft.mshtml.dll, Infragistics Winform controls이 있습니다.) 그렇다면 ClickOnce로는 방법이 없는걸까요? 그렇지는 않습니다. 게시하려는 프로젝트의 속성 창을 열고 게시 속성 탭을 열면 필수구성요소를 변경하는 버튼이 있습니다. 이 버튼을 클릭하면 다음과 같은 다이얼로그가 출력됩니다. (항목은 개발자 머신마다 다를 수 있습니다.)

사용자 삽입 이미지

설치할 필수 구성 요소 리스트를 살펴보면 .NET Framework, MDAC, Crystal Reports 등이 있음을 알 수 있습니다. 이 필수 구성 요소들은 ClickOnce 게시한 제품이 설치되기 전에 먼저 설치되어야 하는 요소들입니다. 대표적인 요소가 .NET Framework 2.0 이겠죠.

필수 구성 요소를 추가하는 방법은 다음과 같습니다.

  1. 프로젝트 속성 창에서 게시 속성을 엽니다.
  2. <설치 모드 및 설정> 그룹에서 <필수 구성 요소> 버튼을 클릭합니다.
  3. 필수 구성 요소 다이얼로그에서 <필수 구성 요소를 설치하기 위한 설치 프로그램 만들기> 체크박스를 체크합니다.
  4. <설치할 필수 구성 요소 선택> 리스트에서 필요한 구성 요소를 선택합니다.
  5. <필수 구성 요소의 설치 위치를 지정하십시오.> 라디오 버튼 그룹에서 다운로드 위치를 선택합니다.
  6. <확인> 버튼을 클릭하여 작업을 완료합니다.
  7. 게시합니다.

위의 작업을 수행하여 게시할 경우 필수 구성 요소들이 제품이 설치되기 전에 먼저 설치됩니다. 간단하죠. 하지만 문제가 있습니다. 위 절차 중 4. <설치할 필수 구성 요소 선택> 리스트에 없는 요소를 추가하려면 어떻게 해야 할까요? 위에서 언급했던 Microsoft.mshtml.dll 이나 써드파티 컴포넌트의 경우 말이죠. 이런 경우를 위해 MS에서는 사용자 정의 필수 구성 요소 선택하는 방법에 대해 친절히 설명하고 있습니다. 관련 MSDN URL은 참고문헌을 참고하세요.


하지만 위 문서에서 결정적으로 빠진 내용이 있습니다. 위 문서 중반 부분에 이런 내용이 있습니다.

새 구성 요소 패키지를 만들려면 다음을 제공해야 합니다.

  • EXE 또는 MSI 파일 형식의 재배포 가능 구성 요소
  • 패키지의 모든 언어 중립 메타데이터가 포함된 제품 매니페스트(product.xml). 이 매니페스트에는 모든 지역화된 재배포 가능 구성 요소 버전에 공통되는 메타데이터가 포함되어 있습니다.
  • 언어별 메타데이터가 포함된 패키지 매니페스트(package.xml). 이 매니페스트에는 일반적으로 지역화된 오류 메시지가 포함되어 있습니다. 구성 요소에는 지역화된 버전의 해당 구성 요소별로 최소한 하나의 패키지 매니페스트가 있어야 합니다.

첫 번째 항목은 Windows Installer로 설치파일을 만드는 것을 말합니다. Windows Installer로 설치파일을 만드는 방법은 문서 마지막 참고문헌을 참고하세요.
문제는 두 번째와 세 번째 항목입니다. 제품 매니페스트와 패키지 매니페스트 파일을 구성하는 것인데 구성하는 방법이 쉽지 않습니다. 자세한 내용은 제품 및 패키지 스키마 참조 문서에 있지만 살펴보면 이해하기가 만만치 않습니다. 무엇보다 우리가 원하는 것은 PackageFile이 msi(Windows Installer)일 경우 <InstallChecks> 작성하는 방법과 <Commands> 작성하는 방법인데 말이죠, 이와 관련해서는 예문이 없습니다. 그래서 이것 저것 장님 문고리 잡듯이 MSDN에 있는 샘플 매니페스트를 수정해가면서 게시하는데 3~4분 걸리는 프로젝트를 테스트해 보았습니다. 근 15여 차례 정도? 계속 Install error가 생겨서 install log를 살펴보니 product.xml(제품 매니페스트)의 <InstallChecks>와 <Commands>의 <InstallConditions>에서 오류가 생기더군요. 도저히 이런 방법으론 안되겠다 싶어 제품 및 패키지 스키마 참조를 다시 읽어 보았습니다. 살펴보니 <InstallChecks> 하위 요소에 <MsiProductCheck>란 놈이 있더군요. MsiProductCheck를 사용해서 구글에서 검색해 결국 답을 얻었습니다. MS 포럼에 질문이 올라와 있더군요. 링크는 다음과 같습니다. http://forums.microsoft.com/msdn/showpost.aspx?postid=5396&siteid=1 위 링크에서 얻은 내용을 토대로 MSI 설치 파일(Windows Installer 설치 파일)을 사용한 사용자 정의 필수 구성 요소를 구성하는 방법을 정리해 보았습니다.

솔루션

ClickOnce에 MSI 설치 파일 필수 구성 요소 추가하는 절차는 다음과 같습니다.
편의상 msi 파일은 미리 만들어져 있고 파일명은 PreInstall.msi로 합니다.

  1. \Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bootstrapper\Package 폴더로 이동합니다.
  2. 폴더를 만듭니다. (예: PreInstall)
  3. 새로 만든 폴더에 PreInstall.msi 파일을 복사합니다.
  4. product.xml 파일을 새로 만듭니다. (표-1)의 코드를 복사해 넣습니다.
  5. (표-1)의 코드에서 PreInstall 문자열을 적절하게 변경하시면 되고, 중요한 부분은 <InstallChecks><MsiProductCheck>의 Product 속성입니다. 이 곳에는 Visual Studio 2005의 설치 프로젝트 속성에 있는 ProdcutCode 값을 복사해 넣으면 됩니다. 중괄호({…})를 포함한 값입니다.
  6. PreInstall 폴더에 Ko폴더를 새로 만듭니다. 새로 만든 Ko폴더로 이동합니다.
  7. eula.txt 파일을 만들고 소프트웨어 사용권 내용을 입력합니다.(아무런 내용이든 상관없습니다.)
  8. package.xml 파일을 만들고 (표-2)의 내용을 복사해 넣습니다.
  9. PreInstall 문자열을 적절하게 변경시키면 됩니다.

(표-1)

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

<Product

xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"

ProductCode="PreInstall">

<!-- Defines list of files to be copied on build -->

<PackageFiles>

<PackageFile Name="PreInstall.msi"/>

</PackageFiles>

<RelatedProducts>

<DependsOnProduct Code="Microsoft.Net.Framework.2.0" />

</RelatedProducts>

<InstallChecks>

<MsiProductCheck

Property="PreInstall"

Product="{XXXX…}"

/>

</InstallChecks>

<Commands Reboot="Defer">

<Command PackageFile="PreInstall.msi" Arguments="/quiet /qn" EstimatedInstallSeconds="10" EstimatedInstalledBytes="1000000">

<InstallConditions>

<BypassIf Property="PreInstall" Compare="ValueEqualTo" Value="5"/>

<!-- Block install if there is no .NET Framework -->

</InstallConditions>

<ExitCodes>

<ExitCode Value="0" Result="Success"/>

<DefaultExitCode Result="Fail" FormatMessageFromSystem="true" String="GeneralFailure"/>

</ExitCodes>

</Command>

</Commands>

</Product>


(표-2)

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

<Package

xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"

Name="DisplayName"

Culture="Culture"

LicenseAgreement="eula.txt">

<PackageFiles>

<PackageFile Name="eula.txt"/>

</PackageFiles>

<!-- Defines a localizable string table for error messages-->

<Strings>

<String Name="DisplayName">PreInstall</String>

<String Name="Culture">ko</String>

<String Name="GeneralFailure">

A failure occurred attempting to install PreInstall

</String>

</Strings>

</Package>



위의 절차는 내가 만든 MSI 설치파일을 ClickOnce 게시 프로젝트에 추가하는 최소한의 절차입니다. 좀 더 자세한 내용은 MSDN을 참조하십시오.


참고문헌

1. MSDN : ClickOnce와 Windows Installer 비교
2. MSDN : 사용자 지정 필수 구성 요소 추가
3. MSDN : 제품 및 패키지 스키마 참조
4. MSDN : Use the Visual Studio 2005 Bootstrapper to Kick-Start Your Installation
5. MS Forums : MsiProductCheck element

+ Recent posts