다음을 통해 공유


애플리케이션 복원력: Windows 설치 관리자의 숨겨진 기능 잠금 해제

 

마이클 샌포드
701 소프트웨어

2005년 3월

요약: Windows Installer에는 개발 커뮤니티에서 거의 눈에 띄지 않는 몇 가지 기능이 있습니다. 이러한 기능을 사용하면 애플리케이션이 런타임에 자체적으로 복구하거나 사용자와 애플리케이션의 상호 작용에 따라 선택적 구성 요소를 설치할 수 있습니다. (인쇄된 10페이지)

MSI 통합 샘플 Code.msi다운로드합니다.

콘텐츠

소개
셸 통합을 통한 복원력
Windows Installer API 소개
주요 애플리케이션 API
챌린지 #1: Self-Invoked 복원력
과제 #2: 주문형 설치
결론

소개

개발자는 이상적인 환경, 이상적인 시스템 및 성공적인 설치 후 애플리케이션을 사용하는 이상적인 사용자가 실행하는 애플리케이션을 생각하는 경향이 있습니다. 실제로 애플리케이션이 성공적으로 설치되면 해당 사용자의 수명은 이제 막 시작되었습니다. 애플리케이션이 안정적이고 기능적인 상황에서 직면할 수 있는 과제는 많지만 대부분의 애플리케이션은 애플리케이션을 작동하지 않게 만들 수 있는 운영 환경의 변경 내용을 처리할 준비가 되어 있지 않습니다.

Windows Installer는 애플리케이션을 안정적으로 유지하는 데 상당한 진전을 이룬 복원력 기능을 제공하지만, 이 기능은 사용자가 셸과 상호 작용하는 동안 수행하는 특정 작업을 기반으로 하여 Windows Installer가 애플리케이션 구성 문제를 감지하고 복구 단계를 수행할 수 있는 "진입점"을 제공합니다.

다음은 Windows 설치 관리자 "진입점"의 짧은 목록입니다.

  • 바로 가기. Windows Installer는 사용자에게 투명하지만 Windows Installer가 애플리케이션을 시작하기 전에 지정된 애플리케이션 설치의 상태를 확인하기 위해 셸 통합을 통해 사용하는 추가 메타데이터를 포함하는 특수한 유형의 바로 가기를 도입합니다.
  • 파일 연결. Windows Installer는 사용자가 셸을 사용하여 문서 또는 파일을 열 때 Windows Installer가 연결된 애플리케이션을 시작하기 전에 애플리케이션을 확인할 수 있도록 문서 또는 파일의 연결된 애플리케이션에 대한 호출을 가로채는 메커니즘을 제공합니다.
  • COM 광고. Windows Installer는 COM 하위 시스템에 연결되는 메커니즘을 제공하므로 Windows Installer에서 설치하고 이 기능을 사용하도록 구성된 COM 구성 요소의 instance 만드는 모든 애플리케이션은 Windows Installer가 해당 구성 요소의 설치 상태를 확인한 후 해당 구성 요소의 instance 받습니다.

특정 상황에서 Windows Installer의 기본 제공 복원력 기능이 애플리케이션 구성의 모든 문제를 감지하지 못하거나 필요한 진입점이 활성화되지 않는 방식으로 애플리케이션이 작동할 수 있습니다. 다행히 Windows Installer 팀의 스마트 팀은 이 과제를 이해하고 풍부한 Windows Installer API를 통해 추가 복원력 기능을 사용할 수 있게 했습니다.

셸 통합을 통한 복원력

Windows Installer API에서 제공하는 고급 복원력 기능으로 넘어가기 전에 Windows Installer를 사용하여 앱을 배포할 때 일반적으로 무료로 제공되는 일반적인 복원력 시나리오를 살펴보겠습니다.

이 시나리오에서는 SimplePad를 호출하는 간단한 텍스트 편집 애플리케이션을 배포합니다. 설치를 만들려면 Microsoft의 오픈 소스 WiX 도구 키트를 사용하려고 하지만(자세한 내용은 https://sourceforge.net/projects/wix/.참조) 원하는 도구를 사용하여 동일한 작업을 수행할 수 있습니다.

<Directory Id="TARGETDIR" Name="SourceDir">
<Component Id="SimplePad" Guid="BDDFA5DC-BD69-4232-998E-5167814C21B9" 
  KeyPath="no">
  <File Id="SimplePadConfig" Name="SP.cfg"
    src="$(var.SrcFilesPath)SimplePad.exe.config"
    LongName="SimplePad.exe.config" Vital="yes" KeyPath="no" DiskId="1" />
  <File Id="SimplePad" Name="Simple~1.exe"
    src="$(var.SrcFilesPath)SimplePad.EXE" LongName="SimplePad.exe" Vital="yes"
    KeyPath="yes" DiskId="1" >
  <Shortcut Id="SC1" Advertise="yes"  Directory="ProgramMenuFolder"
    Name="SimpPad" LongName="Run SimplePad"  />
  </File>
</Component>
<Directory Id="ProgramMenuFolder" Name="ProgMenu"></Directory>
</Directory>

위의 XML 조각에서 볼 수 있듯이 하나의 파일(SimplePad.exe)과 사용자의 시작 메뉴에 있는 단일 바로 가기를 사용하여 매우 간단한 설치를 만들었습니다. 이 예제에서 만드는 바로 가기는 Windows Installer가 애플리케이션의 상태를 검색하고 필요에 따라 복구하는 데 사용할 진입점이라는 점에 유의해야 합니다.

이 시점에서 설치 관리자를 빌드하고, 애플리케이션을 설치하고, 새로 만든 시작 메뉴 바로 가기를 사용하여 실행할 수 있습니다. 예상대로 애플리케이션은 의도한 대로 정확하게 작동합니다. Windows Installer의 기본 제공 복원력 기능을 테스트하려면 SimplePad.exe 파일을 삭제하고 시작 메뉴 바로 가기에서 애플리케이션을 실행해 봅니다. 다시 말하지만, 예상대로 Windows Installer는 SimplePad.exe 누락된 것을 감지하고 복구가 시작됩니다. 복구 작업 중에 Windows Installer는 설치 패키지의 내부적으로 캐시된 복사본에서 필요한 구성 정보를 읽고 마지막으로 누락된 파일을 대체하여 설치된 원래 위치에 없는 경우 원본 설치 미디어에 대한 메시지를 사용자에게 표시합니다. 복구 작업이 완료되면 애플리케이션이 정상적으로 시작됩니다.

그림 1. 복구 작업 진행 중

애플리케이션 복원력은 여기에서 언급할 만한 몇 가지 다른 메커니즘을 통해 Windows Installer에서도 제공됩니다. 애플리케이션을 고가용성 상태로 유지하는 두 번째 가장 일반적인 방법은 Windows Installer 파일 연결을 통해서입니다. 이 메커니즘은 Windows Installer 바로 가기와 거의 동일한 방식으로 작동하지만 애플리케이션의 실행 파일에 직접 연결하는 대신 등록된 파일 형식으로 연결됩니다. 그림 2에서 볼 수 있듯이 Windows Installer 파일 연결은 표준 파일 연결에서 사용하는 것과 동일한 메커니즘을 사용하여 정의됩니다. 단 한 가지 예외가 있습니다. 그림 2에서는 일반적인 "shell\Open\command" 레지스트리 키 아래에 추가 값이 나열됩니다. 추가 값("명령")은 Windows 셸 내에서 파일을 두 번 클릭할 때마다 Windows Installer가 표시되는 위치입니다. "Darwin 설명자"라고도 하는 이 암호화된 문자열은 실제로 특정 제품, 구성 요소 및 기능의 인코딩된 표현입니다. 이 추가 값이 있는 경우 Windows Installer는 데이터를 디코딩하고 이를 사용하여 해당 제품 및 구성 요소에 대한 검사를 수행합니다. 구성 요소가 누락되거나 손상된 것으로 확인되면 Windows Installer가 복구를 시작하여 누락된 파일 또는 데이터를 복원하고 마지막으로 참조된 애플리케이션을 정상적으로 시작하여 적절한 명령줄 옵션을 전달합니다.

그림 2. 파일 연결에 대한 "Darwin 설명자" 보기

오늘 논의할 최종 복원력 메커니즘은 일반적으로 COM Advertising이라고 합니다. COM Advertising의 메커니즘을 살펴보기 전에 그 뒤에 있는 사용 사례를 이해하는 것이 중요합니다. 실시간 우편 요금을 제공하는 COM 기반 공유 라이브러리를 제공하는 구성 요소 공급업체라고 가정해 보겠습니다. 이 구성 요소는 다양한 제품에서 사용할 수 있으므로 최종 사용자 시스템의 단일 공유 위치에 설치됩니다. 구성 요소가 항상 동일한 위치에 설치되도록 하고 구성 요소를 항상 항상 사용할 수 있도록 하려면 COM Advertising을 활용하도록 올바르게 구성된 병합 모듈에서 고객에게 배송합니다. 물론 솔루션은 사용자 인터페이스가 없는 단일 .dll 파일로 제공되므로 복원력의 다른 메커니즘만으로는 충분하지 않습니다. 이 경우 COM Advertising을 사용하여 구성 요소가 제대로 설치되고 사용자 시스템에 등록되도록 할 수 있습니다. 애플리케이션이 일반적인 COM 메커니즘을 통해 이 구성 요소의 instance 만들면 Windows Installer는 파일 연결과 동일한 방식으로 프로세스에 "후크"됩니다. 그림 3에서는 이번에는 구성 요소의 COM 등록을 위해 "Darwin 설명자"가 InprocServer32 레지스트리 값에 저장됩니다. 다시 말하지만, 이 정보는 디코딩되고 Windows Installer에서 구성 요소가 제대로 설치 및 구성되었는지 확인하고 필요에 따라 복구를 수행한 후 구성 요소의 instance 호출 애플리케이션에 반환하는 데 사용됩니다.

이 고유한 기능은 구성 요소를 사용하여 애플리케이션과 완전히 독립적으로 작동한다는 점을 주목할 가치가 있습니다. 즉, 구성 요소를 사용하는 애플리케이션이 Windows Installer를 사용하여 설치되지 않은 경우에도 호출 애플리케이션이 VBScript일지라도 구성 요소에서 사용하는 COM Advertising이 계속 제대로 작동합니다.

그림 3. COM 서버에 대한 "Darwin 설명자" 보기

지금까지 설명한 모든 항목은 한 줄의 코드를 작성할 필요 없이 Windows Installer의 기능을 활용했지만 이제는 더 풍부하고 강력한 구현으로 넘어갈 차례입니다.

Windows Installer API 소개

Windows Installer의 기본 동작은 이전 시나리오에서 잘 작동했지만 실제 환경에서는 약간 더 정교한 애플리케이션이 있는 경우가 많습니다. 더 어려운 시나리오를 처리하도록 샘플 시나리오를 확장해 보겠습니다.

종종 애플리케이션은 둘 이상의 실행 파일로 구성됩니다. 한 가지 예는 업데이트 프로그램 블록에 표시된 대로 부트스트래퍼 실행 파일을 사용하여 애플리케이션에 대한 업데이트를 검사 설치하는 애플리케이션일 수 있습니다. 이 경우 첫 번째 실행 파일은 사용자가 시작 메뉴에서 바로 가기를 클릭할 때 호출되는 실행 파일입니다. 그러면 애플리케이션의 기본 사용자 인터페이스가 포함된 두 번째 실행 파일이 시작됩니다. 설치가 구성된 방법에 따라 기본 애플리케이션 실행 파일의 문제가 Windows Installer 엔진에서 검색되지 않을 가능성이 있습니다. 한 가지 옵션은 런타임 환경을 검사하는 시작 시 실행되는 많은 코드를 작성하는 것일 수 있지만 실행 파일 자체가 누락되거나 손상되어 문제를 쉽게 복구할 수 없는 경우에는 작동하지 않습니다. 훨씬 더 효과적인 솔루션은 배포 패키지에 이미 정의된 애플리케이션 구성에 대한 Windows Installer의 지식을 활용하는 것입니다.

Windows Installer API는 사용자가 셸과 상호 작용할 때 사용하는 애플리케이션의 무결성을 확인하기 위한 동일한 메커니즘을 노출합니다. 애플리케이션 내에서 이러한 API 호출을 사용하면 앞에서 설명한 셸 "진입점"에 의존하지 않고도 동일한 이점을 얻을 수 있습니다.

다음은 Windows Installer의 셸 통합 복원력 기능에서 다루지 않는 시나리오 목록입니다.

  • OS로 시작하는 앱(레지스트리 키 실행 또는 한 번 실행)
  • 시스템 서비스
  • 예약형 작업
  • 다른 앱에서 실행되는 앱
  • 명령줄 앱

위의 목록에 추가할 수 있는 더 많은 시나리오가 있다고 확신하지만 아이디어를 얻을 수 있다고 생각합니다. 다음 예제에서는 앞에서 설명한 셸 통합 기능에 의존하지 않고 Windows Installer 복원력의 이점을 얻을 수 있는 방법을 보여 줍니다. 완료되면 이러한 개념을 가져와 실행 코드 실행과 관련된 거의 모든 시나리오에 쉽게 적용할 수 있습니다.

주요 애플리케이션 API

몇 가지 예제 시나리오를 살펴보기 전에 애플리케이션 내에서 사용할 수 있는 몇 가지 주요 Windows Installer API를 살펴보겠습니다. 이러한 각 API의 사용에 대한 자세한 내용은 플랫폼 SDK의 Windows Installer Finction 참조 를 참조하세요.

주요 Windows 설치 관리자 함수 설명
MsiProvideComponent 구성 요소의 설치된 위치를 검색하여 필요에 따라 구성 요소를 설치하거나 복구하여 구성 요소를 사용할 수 있는지 확인합니다.
MsiQueryFeatureState 지정된 기능의 설치 상태를 반환합니다. 예를 들어 이 함수는 기능이 설치되어 있는지, 설치되지 않았거나, 보급되었는지를 알려줍니다.
MsiQueryProductState 제품의 설치 상태를 반환합니다. 예를 들어 이 함수는 제품이 설치, 보급, 다른 사용자용으로 설치되었는지 또는 전혀 설치되지 않은지 알려줍니다.
MsiConfigureProduct
MsiConfigureProductEx
이러한 두 함수를 사용하면 프로그래밍 방식으로 애플리케이션을 설치하거나 제거할 수 있습니다. MsiConfigureProductEx 는 명령줄에서 일반적으로 수행하는 것과 유사한 옵션을 지정할 수 있도록 하여 더 큰 제어를 제공합니다.
MsiConfigureFeature 이 함수를 사용하면 애플리케이션의 특정 기능을 설치, 제거 또는 보급할 수 있습니다.
MsiGetUserInfo 이 함수는 제품의 설치 시퀀스 중에 수집된 사용자 이름, organization 및 제품 일련 번호를 반환합니다.
MsiGetComponentPath
MsiLocateComponent
이러한 두 함수는 대상 시스템에서 구성 요소 파일 또는 레지스트리 키의 물리적 위치를 결정하는 데 도움이 됩니다. MsiGetComponentPath는 특정 제품에 의해 설치된 구성 요소의 instance 경로를 반환하고 MsiLocateComponent는 ANY 제품에 의해 설치된 구성 요소의 첫 번째 instance 반환합니다.

챌린지 #1: Self-Invoked 복원력

이전에는 시스템에서 애플리케이션의 실행 파일을 실제로 삭제하고 바로 가기를 사용하여 Windows Installer가 누락된 파일을 다시 설치하여 문제를 감지하고 복구할 수 있는 매우 기본적인 시나리오에 대해 설명했습니다. 이 시나리오는 Windows Installer가 활용하는 셸 통합을 보여 주는 데 잘 작동했지만 이러한 개념을 더 자세히 살펴보기 위해 좀 더 정교한 시나리오를 살펴보겠습니다.

이 시나리오에서 애플리케이션은 단일 .exe 파일과 애플리케이션에 중요한 구성 정보를 제공하는 여러 텍스트 파일로 구성됩니다.

가상 소프트웨어 회사의 기술 지원 담당자는 사용자가 설치에서 만든 시작 메뉴 바로 가기를 사용하는 대신 Windows Explorer 실행 파일을 두 번 클릭하여 애플리케이션을 직접 실행하기 때문에 Windows Installer에서 애플리케이션 구성 문제가 해결되지 않는다는 것을 나타내는 많은 지원 요청을 받고 있습니다.

팀의 상주 배포 전문가와 협의한 후 엔지니어 팀은 애플리케이션이 제대로 구성되었는지 확인하기 위해 시작 시 자체 복원력 검사 수행하여 애플리케이션이 크게 도움이 될 것이라고 결정합니다. 이를 위해 팀은 MsiProvideComponent API에 대한 호출을 추가하여 애플리케이션의 설치 패키지에 정의된 중요한 구성 요소가 제대로 설치되고 구성되었는지 확인합니다.

<DllImport("msi.dll")> _
Private Shared Function MsiProvideComponent(ByVal szProduct As String, ByVal _
 szFeature As String, ByVal szComponent As String, ByVal dwInstallMode As _
 MSI_REINSTALLMODE, ByVal lpPathBuf As System.Text.StringBuilder, ByRef _
 pcchPathBuf As IntPtr) As Integer
End Function

Public Shared Function ProvideComponent(ByVal productCode As String, ByVal _
 featureName As String, ByVal compID As String) As String
  Dim iRet As Integer
  Dim cbBuffer As Integer = 255
  Dim buffer1 As New System.text.StringBuilder(cbBuffer)
  Dim pSize As New IntPtr(cbBuffer)
  iRet = MsiProvideComponent(productCode, featureName, compID, _
   MSI_INSTALLMODE.INSTALLMODE_DEFAULT, buffer1, pSize)
  Return buffer1.ToString
End Function

이 코드를 더 잘 캡슐화하기 위해 WIHelper 라는 새 클래스가 프로젝트에 추가되어 Windows Installer API 메서드 선언 및 래퍼 메서드를 수용합니다. 이 코드를 호출하는 것은 기본 양식의 Load 이벤트 처리기에 몇 줄을 추가하는 간단한 문제였습니다.

Private CONST PRODUCTID As String = "PRODUCT_GUID_HERE"
Private CONST MAIN_FEATUREID As String = "DefaultFeatureKey"
Private CONST COMPID_1 As String = "COMP1_GUID_HERE"
Private CONST COMPID_2 As String = "COMP2_GUID_HERE"
Private Sub MainForm_Load() Handles MyBase.Load
  If WIHelper.IsProductInstalled(PRODUCTID) Then
    WIHelper.ProvideComponent(PRODUCTID, MAIN_FEATUREID, COMPID_1)
    WIHelper.ProvideComponent(PRODUCTID, MAIN_FEATUREID, COMPID_2)
  End If
End Sub
 

위의 샘플 코드에서는 애플리케이션이 실제로 설치 패키지를 통해 설치되었는지 여부를 확인하기 위해 먼저 테스트합니다. 개발 환경에서 디버깅하는 경우에도 애플리케이션이 계속 제대로 작동하도록 하려면 이 개념이 중요합니다. 이를 위해 도우미 클래스에서 IsProductInstalled라는 메서드를 호출합니다. 이 메서드는 MsiQueryProductState 를 호출하여 제품이 시스템에 설치되었는지 확인합니다. IsProductInstalled를 호출하면 제품이 설치되었음을 알 수 있는 경우 도우미 클래스에서 ProvideComponent 메서드를 일련의 호출합니다. 이 메서드는 다시 MsiProvideComponent API를 둘러싼 간단한 래퍼로, 지정된 구성 요소의 전체 경로를 반환하고 구성 요소가 제대로 설치되어 사용할 준비가 되었는지 확인합니다. 특정 제품의 요구 사항에 따라 사용자가 애플리케이션을 완전히 사용할 수 있도록 원하는 만큼 ProvideComponent 메서드를 호출할 수 있습니다.

과제 #2: 주문형 설치

우리의 가상 회사 영업 임원은 고객이 SimplePad와 함께 제공되는 표준 템플릿 세트를보고 싶다는 많은 피드백을 듣고 있습니다. 일부 고객은 이 기능에 대한 강한 열망을 표명했지만, 다른 고객은 대부분의 사용자가 필요로 하지 않을 수 있는 불필요한 데이터를 설치하는 것에 대해 우려를 표명했습니다.

이 새로운 요구 사항을 처리하는 방법을 논의하는 엔지니어를 덮어 본 후, 용감한 설치 엔지니어가 뛰어들어 Windows Installer가 소량의 추가 코딩으로 이 작업을 쉽게 처리할 수 있다고 지적합니다.

몇 가지 빠른 계획 후에 팀은 애플리케이션의 파일 메뉴에서 새 템플릿 메뉴 항목을 구현하기로 결정합니다. 템플릿 기능이 사용자 시스템에 로컬로 설치된 경우 사용 가능한 각 템플릿을 나열하는 플라이아웃 메뉴와 템플릿 기능을 제거하는 옵션이 표시됩니다. 템플릿 기능이 설치되지 않은 경우 템플릿 플라이아웃 메뉴에는 단일 항목이 있으므로 사용자가 추가 템플릿을 설치할 수 있습니다.

Private Sub mnuFile_Popup(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles mnuFile.Popup
  Dim newItem As MenuItem
  With mnuTemplates.MenuItems
    .Clear()
    If WIHelper.IsFeatureInstalled(PRODUCTID, TEMPLATES_FEATUREID) Then
      Dim dirInfo As New DirectoryInfo(Application.ExecutablePath)
      For Each dirFile As FileInfo In dirInfo.Parent.GetFiles("*.tpl")
        Dim mi As New MenuItem(Path.GetFileNameWithoutExtension(dirFile.Name))
        AddHandler mi.Click, AddressOf OpenTemplate
        .Add(mi)
      Next
      .Add("-")
      newItem = New MenuItem("Uninstall Templates")
      AddHandler newItem.Click, AddressOf UninstallTemplates
      .Add(newItem)
    Else
      newItem = New MenuItem("Install Templates")
      AddHandler newItem.Click, AddressOf InstallTemplates
      .Add(newItem)
    End If
  End With
End Sub

여기서 볼 수 있듯이 템플릿 기능이 설치되어 있는지 먼저 검사. 이 경우 "tpl" 확장명이 있는 애플리케이션 폴더의 파일을 열거하고 메뉴에 각 템플릿의 이름을 추가합니다. 그렇지 않은 경우 사용자가 템플릿을 설치하는 옵션을 추가하기만 하면 됩니다. 이를 살펴보기 전에 먼저 템플릿 기능이 설치되어 있는지 여부를 확인하는 방법을 살펴보겠습니다.

<DllImport("msi.dll")> _
Private Shared Function MsiQueryFeatureState(ByVal szProduct As String, 
ByVal szFeature As String) As MSI_INSTALLSTATE
End Function    
Public Shared Function IsFeatureInstalled(ByVal pid As String, ByVal fid As String) As Boolean
  Return MsiQueryFeatureState(pid, fid) = MSI_INSTALLSTATE.INSTALLSTATE_LOCAL
End Function

이 간단한 함수에서는 단순히 Windows Installer MsiQueryFeatureState 함수를 호출하여 애플리케이션의 ProductCode 및 문의하는 기능의 이름을 전달합니다. Windows Installer가 INSTALLSTATE_LOCAL 반환하는 경우 기능이 로컬로 설치되었음을 의미하기 때문에 true를 반환합니다.

템플릿 기능 설치 및 제거는 쉽게 수행할 수 있습니다.

<DllImport("msi.dll")> _
Private Shared Function MsiConfigureFeature(ByVal szProduct As String, ByVal szFeature As String, ByVal eInstallState As MSI_INSTALLSTATE) As Integer
End Function

Public Shared Function InstallFeature(ByVal pid As String, ByVal fid As String)
  As Boolean
  Return MsiConfigureFeature(pid, fid, MSI_INSTALLSTATE.INSTALLSTATE_LOCAL) = ERROR_SUCCESS
End Function

Public Shared Function UninstallFeature(ByVal pid As String, ByVal fid As String) As Boolean
  Return MsiConfigureFeature(pid, fid, 
MSI_INSTALLSTATE.INSTALLSTATE_ABSENT) = ERROR_SUCCESS
End Function

사용자가 "템플릿 설치" 메뉴 항목을 클릭하면 ProductCode, 구성하려는 기능의 이름 및 기능을 로컬로 설치할 것을 나타내는 열거형 값을 사용하여 MsiConfigureFeature를 호출합니다. 템플릿 기능이 설치된 동안 사용자에게 Windows Installer 진행률 대화 상자가 잠시 표시됩니다. 대화 상자가 사라지면 템플릿이 설치되고 사용할 준비가 됩니다. 사용자가 파일 메뉴로 돌아가면 템플릿 하위 메뉴가 위에서 설명한 대로 템플릿 이름으로 채워집니다.

결론

Windows Installer에서 노출하는 "무료" 기능 및 API를 활용하면 지원 비용을 줄이고 애플리케이션 안정성을 높이며 사용자 환경을 향상시키는 데 유용한 몇 가지 멋진 기능이 제공됩니다. 여기에 설명된 예제는 본질적으로 다소 간단하지만 고유한 솔루션을 구현하기 위한 좋은 출발점이 되기를 바랍니다. 사용 가능한 API 중 일부를 살펴보았지만 모두 다루지는 않았습니다. 잠시 시간을 내어 Windows Installer API의 모든 기능을 살펴보시면 Windows Installer의 비교적 미개발된 기능을 얼마나 쉽게 활용할 수 있는지 유쾌하게 놀라게 될 것입니다.

 

작성자 정보

Michael Sanford 는 701 Software(http://www.701software.com)의 사장 겸 수석 소프트웨어 설계자입니다. 701을 형성하기 전에 마이클은 제로 G 소프트웨어에 의해 인수 된 ActiveInstall Corporation의 사장 겸 CEO였습니다. ActiveInstall은 Windows Installer Authoring 솔루션에 대한 악명을 달성했습니다. Michael은 MCSD(Microsoft Certified Solution Developer), MCSE(Microsoft Certified Systems Engineer) 및 Windows Installer MVP입니다. 에서 Michael의 블로그를 http://msmvps.com/michael읽을 수 있습니다.