MSI를 통해 제거 할 때만 발생하는 WiX 사용자 지정 동작을 추가하는 방법은 무엇입니까?


161

제거시 전체 디렉토리를 삭제하도록 MSI 설치 프로그램 ( WiX를 통해 생성됨)을 수정하고 싶습니다 .

WiX 의 RemoveFileRemoveFolder옵션을 이해 하지만 설치 후 작성된 컨텐츠가있는 전체 폴더를 반복적으로 삭제하기에 충분하지 않습니다.

비슷한 스택 오버플로 질문 WiX 제거시 파일 제거 질문을 발견 했지만 폴더를 삭제하기 위해 배치 스크립트 호출을 사용하여 더 간단하게 수행 할 수 있는지 궁금합니다.

WiX를 사용한 것은 이번이 처음이지만 여전히 맞춤 작업 이 중단 됩니다. 설치 제거시 배치 스크립트를 실행하는 사용자 정의 조치의 기본 예제는 무엇입니까?

답변:


188

편집 : 아마도 현재 바로 아래 의 답변을 볼 수 있습니다 .


이 주제는 오랫동안 두통이었습니다. 나는 마침내 그것을 알아 냈습니다. 온라인에는 몇 가지 솔루션이 있지만 실제로는 작동하지 않습니다. 물론 문서도 없습니다. 따라서 아래 차트에는 다양한 설치 시나리오에 사용할 수있는 몇 가지 속성과 그 값이 있습니다.

대체 텍스트

따라서 필자의 경우에는 업그레이드, 복구 또는 수정이 아닌 제거에서만 실행되는 CA를 원했습니다. 위의 표에 따르면 사용해야했습니다.

<Custom Action='CA_ID' Before='other_CA_ID'>
        (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>

그리고 효과가있었습니다!


25
해당 차트의 값이 정확합니까? 왜 REMOVE = "ALL"을 추가해야합니까? NOT UPGRADINGPRODUCTCODE는 설치 제거 (차트에 따름)에 대해서만 참이므로 (NOGRADEINGPRODUCTCODE) 및 (REMOVE = "ALL")도 설치 제거에만 참입니다. REMOVE = "ALL"은 불필요한 것 같습니다.
Todd Ropog

2
@ToddRopog에 동의합니다. 예제와 진리표가 동의하지 않는 것 같습니다. 정말 맞습니까?
Tim Long

19
진리표는 약간 잘못되었습니다. NOT UPGRADINGPRODUCTCODE도 최초 설치시에도 적용됩니다
Neil


1
확인하십시오 : 설치됨과 설치됨이 다릅니다. Windows Installer에서 설치됨 만 설정합니다. INSTALLED가 작동한다고 생각하지 않습니다.
Micha Wiedenmann

140

yaluna의 답변에 여러 가지 문제가 있으며 속성 이름은 대소 문자를 구분하며 Installed철자가 맞습니다 ( INSTALLED작동하지 않습니다). 위의 표는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

또한 전체 수리 및 제거를 가정하면 실제 속성 값은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

윅스 식 구문 문서는 말합니다 :

이 표현식에서 특성 이름을 사용할 수 있습니다 (대소 문자 구분).

속성은 Windows Installer 안내서에 설명되어 있습니다 (예 : Installed )

편집 : 첫 번째 테이블에 작은 수정; 분명히 "제거"도 단지 일어날 수 REMOVE존재 True.


3
REMOVE 또한 변화를위한 설정 보인다
SZX

2
'업그레이드'열은 이전 버전의 제거 순서 또는 새 버전의 설치 순서입니까?
Nick Whaley

1
@NickWhaley : 한동안 살펴 보지 않았지만 "업그레이드"옵션은 이미 설치된 것보다 큰 버전을 설치할 때만 가능하다고 생각합니다.
ahmd0

1
물론 @ ahmd0. 그러나 RemoveExistingProducts 내에는 완전히 다른 속성 집합이있는 중첩 설치가 있습니다. 이것이 '업그레이드'란에 있습니다. 나머지 업그레이드는 '설치'열과 동일합니다.
Nick Whaley

1
@NickWhaley : REMOVE 옵션은 이전 버전의 제거 프로그램을 실행하는 동안 1.0.0에서 1.1.0이 아닌 주요 업그레이드 (예 : 1.0.0에서 2.0.0)에 해당됩니다. 새 버전 설치에서 메이저 업그레이드 중에 사용자 정의 조치를 실행하려면 해당 버전 업그레이드에 대한 업그레이드 MSI 테이블에 정의 된 ActionProperty를 참조해야합니다. symantec.com/connect/articles/msi-upgrade-overview msdn.microsoft.com/en-us/library/aa372379%28v=vs.85%29.aspx
Chaoix

48

이 작업은 사용자 지정 작업으로 수행 할 수 있습니다. 다음에서 맞춤 작업에 굴절을 추가 할 수 있습니다 <InstallExecuteSequence>.

<InstallExecuteSequence>
...
  <Custom Action="FileCleaner" After='InstallFinalize'>
          Installed AND NOT UPGRADINGPRODUCTCODE</Custom>

그런 다음 아래에서 작업을 정의해야합니다 <Product>.

<Product> 
...
  <CustomAction Id='FileCleaner' BinaryKey='FileCleanerEXE' 
                ExeCommand='' Return='asyncNoWait'  />

FileCleanerEXE는 바이너리 (내 경우에는 사용자 정의 작업을 수행하는 작은 C ++ 프로그램)이며 다음과 같이 정의됩니다 <Product>.

<Product> 
...
  <Binary Id="FileCleanerEXE" SourceFile="path\to\fileCleaner.exe" />

실제 트릭 Installed AND NOT UPGRADINGPRODUCTCODE은 사용자 지정 작업 의 조건 이며, 업그레이드 할 때마다 업그레이드가 실제로 제거 된 후 다시 설치되므로 모든 업그레이드에서 작업이 실행되지 않습니다. 파일을 삭제하는 경우 업그레이드 중에 원하지 않을 수 있습니다.

참고 사항 : 전원 및 제어 기능으로 인해 배치 스크립트 대신 C ++ 프로그램과 같은 작업을 수행하는 데 어려움을 겪는 것이 좋습니다. 설치 관리자가 실행됩니다.


3
25 개의 찬성 투표는 가능하지만 정답은 아닙니다. 설치 프로그램의 세계에 오신 것을 환영합니다! :)
Christopher Painter

4
이것은 실제로 작동하지 않습니다. 자신의 설치 폴더에 설치되어있는 fileCleaner.exe를 실행하려면 닭과 계란 문제가 발생합니다. CustomAction"After = 'InstallFinalize'"가 실행됩니다. 이 시점에서 모든 파일이 설치 폴더에서 제거됩니다. 또한 fileCleaner.exe. 따라서 CustomAction을 통해 실행할 수 없습니다. 이 대답은 단순히 잘못되었습니다. 나는 42 upvotes에 대해 궁금하다!
Simon

40

배치 스크립트의 가장 큰 문제는 사용자가 취소를 클릭 할 때 (또는 설치 중에 문제가 발생했을 때) 롤백을 처리하는 것입니다. 이 시나리오를 처리하는 올바른 방법은 RemoveFiles 테이블에 임시 행을 추가하는 CustomAction을 작성하는 것입니다. 이렇게하면 Windows Installer가 롤백 사례를 처리합니다. 솔루션을 볼 때 엄청나게 간단합니다.

어쨌든, 제거 중에 만 액션을 실행하려면 다음을 사용하여 Condition 요소를 추가하십시오.

REMOVE ~= "ALL"

~ =는 대소 문자를 구분하지 않는다고 말합니다 (모든 것이 항상 대문자라고 생각하더라도). 자세한 내용 은 조건 구문대한 MSI SDK 설명서 를 참조하십시오.

추신 : 제가 앉은 후 "아무런 배치 파일이 설치 패키지에서 좋은 솔루션이 될 것"이라고 생각한 적이 없었습니다. 실제로 배치 파일이 포함 된 설치 패키지를 찾으면 제품을 반품하여 환불받을 수 있습니다.


배치 스크립트를 사용하려고했는데 PS 섹션을 보았습니다. 저를 저장해 주셔서 감사합니다 :) Remove ~ = "ALL"이 저에게 효과적이었습니다.
ArNumb

12

내장 된 것보다 사용하기가 더 직관적 인 느낌을주는 일련의 속성이 있습니다. 조건은 ahmd0에서 제공 한 진리표를 기반으로합니다.

<!-- truth table for installer varables (install vs uninstall vs repair vs upgrade) https://stackoverflow.com/a/17608049/1721136 -->
 <SetProperty Id="_INSTALL"   After="FindRelatedProducts" Value="1"><![CDATA[Installed="" AND PREVIOUSVERSIONSINSTALLED=""]]></SetProperty>
 <SetProperty Id="_UNINSTALL" After="FindRelatedProducts" Value="1"><![CDATA[PREVIOUSVERSIONSINSTALLED="" AND REMOVE="ALL"]]></SetProperty>
 <SetProperty Id="_CHANGE"    After="FindRelatedProducts" Value="1"><![CDATA[Installed<>"" AND REINSTALL="" AND PREVIOUSVERSIONSINSTALLED<>"" AND REMOVE=""]]></SetProperty>
 <SetProperty Id="_REPAIR"    After="FindRelatedProducts" Value="1"><![CDATA[REINSTALL<>""]]></SetProperty>
 <SetProperty Id="_UPGRADE"   After="FindRelatedProducts" Value="1"><![CDATA[PREVIOUSVERSIONSINSTALLED<>"" ]]></SetProperty>

샘플 사용법은 다음과 같습니다.

  <Custom Action="CaptureExistingLocalSettingsValues" After="InstallInitialize">NOT _UNINSTALL</Custom>
  <Custom Action="GetConfigXmlToPersistFromCmdLineArgs" After="InstallInitialize">_INSTALL OR _UPGRADE</Custom>
  <Custom Action="ForgetProperties" Before="InstallFinalize">_UNINSTALL OR _UPGRADE</Custom>
  <Custom Action="SetInstallCustomConfigSettingsArgs" Before="InstallCustomConfigSettings">NOT _UNINSTALL</Custom>
  <Custom Action="InstallCustomConfigSettings" Before="InstallFinalize">NOT _UNINSTALL</Custom>

이슈 :


이것은 훌륭한 솔루션입니다. PATCH 및 MSIPATCHREMOVE 조건도 고려해야합니다.
Garet Jax

진리표에서 ahmd0에서 사용하는 UPGRADINGPRODUCTCODE 대신 PREVIOUSVERSIONSINSTALLED를 사용한다는 의미입니까? MSI 속성 참조 페이지 ( docs.microsoft.com/en-us/windows/win32/msi/property-reference ) 에 PREVIOUSVERSIONSINSTALLED에 대한 참조가 없습니다 .
패트릭

속성에 대한 몇 가지 조건자는 ahmd0 테이블의 모든 행 (Installed, REINSTALL, UPGRADINGPRODUCTCODE 및 REMOVE)을 고려하지 않습니다. 이유를 설명해 주시겠습니까?
Patrick

0

C ++ DLL로 별도로 코딩 된 사용자 지정 작업을 사용하고 DLL을 사용하여 다음 구문을 사용하여 제거시 적절한 기능을 호출했습니다.

<CustomAction Id="Uninstall" BinaryKey="Dll_Name" 
              DllEntry="Function_Name" Execute="deferred" />

위의 코드 블록을 사용하여 제거 할 때 C ++ DLL에 정의 된 모든 기능을 실행할 수있었습니다. 참고로, 내 제거 기능에는 현재 사용자 데이터 및 레지스트리 항목 지우기와 관련된 코드가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.