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

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

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

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

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



답변

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


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

대체 텍스트

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

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

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


답변

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

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

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

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

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

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

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

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


답변

이 작업은 사용자 지정 작업으로 수행 할 수 있습니다. 다음에서 맞춤 작업에 굴절을 추가 할 수 있습니다 <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 ++ 프로그램과 같은 작업을 수행하는 데 어려움을 겪는 것이 좋습니다. 설치 관리자가 실행됩니다.


답변

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

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

REMOVE ~= "ALL"

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

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


답변

내장 된 것보다 사용하기가 더 직관적 인 느낌을주는 일련의 속성이 있습니다. 조건은 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>

이슈 :


답변

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

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

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


답변