So, I'm stuck in hell. Come and laugh at me.
I am trying to create a wix installer that does some moderately complex things, and when uninstalled it clears itself correctly after uninstall. This is apparently too much to hope for, because ...
I can use a simple choice between performing custom cleanup actions or delete the installation folder, but not both.
The installer has five user actions: two to bind the SSL certificate to the port and add an ACL for this port, two to remove them and one to launch the application after installation.
If I DO NOT perform two user actions that remove the certificate binding and ACL URL (deleting them or even if they do not work), then the installation folder deleted as expected. If I do two user bindings, the installation folder is NOT deleted. Because I'm terrified.
Custom actions are pretty straight forward. Listen, here they are.
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Impersonate="yes" />
<CustomAction Id="AddHttpsReservation"
Directory="INSTALLFOLDER"
ExeCommand="[SystemFolder]netsh http add urlacl url=https://127.0.0.1:9001/ sddl=D:(A;;GX;;;BU)"
Execute="deferred"
Impersonate="no"
Return="asyncWait" />
<CustomAction Id="AddHttpsBinding"
Directory="INSTALLFOLDER"
ExeCommand="[SystemFolder]netsh http add sslcert ipport=0.0.0.0:9001 certhash=S0M3C3RTHA5H appid={8feef448-1a4f-408f-b6d4-8a90300517ed}"
Execute="deferred"
Impersonate="no"
Return="asyncWait" />
<CustomAction Id="DeleteHttpsReservation"
Directory="INSTALLFOLDER"
ExeCommand="[SystemFolder]netsh http delete urlacl url=https://127.0.0.1:9001/"
Execute="deferred"
Impersonate="no"
Return="asyncWait" />
<CustomAction Id="DeleteHttpsBinding"
Directory="INSTALLFOLDER"
ExeCommand="[SystemFolder]netsh http delete sslcert ipport=0.0.0.0:9001"
Execute="deferred"
Impersonate="no"
Return="asyncWait" />
. ; wix ( , , #, wix, n- ), (ALMOST) , , :
<InstallExecuteSequence>
<Custom Action="LaunchApplication"
After="InstallFinalize">NOT REMOVE~="ALL"</Custom>
<Custom Action="AddHttpsBinding"
Before="InstallFinalize">Not Installed</Custom>
<Custom Action="AddHttpsReservation"
Before="InstallFinalize">Not Installed</Custom>
<Custom Action="DeleteHttpsReservation"
After="InstallInitialize">REMOVE~="ALL"</Custom>
<Custom Action="DeleteHttpsBinding"
After="InstallInitialize">REMOVE~="ALL"</Custom>
</InstallExecuteSequence>
( , Before = "InstallFinalize" , , 1631, , , , , wix )
, , , (, Microsoft , , ). , (1631, ), . , (, , RemoveFolders, , ).
- ( - wix-) !
, , , , ( ):
MSI (s) (0C:C0) [13:25:59:184]: Executing op: FileRemove(,FileName=readme.txt,,ComponentId={F3E98E05-E32A-5DC0-A551-64807B816AC2})
MSI (s) (0C:C0) [13:25:59:185]: Verifying accessibility of file: readme.txt
MSI (s) (0C:C0) [13:25:59:187]: Note: 1: 2318 2:
MSI (s) (0C:C0) [13:25:59:187]: Note: 1: 2327 2: 32 3: C:\Program Files (x86)\DealingWithThisWixBullshitInstaller\
MSI (s) (0C:C0) [13:25:59:188]: Note: 1: 2205 2: 3: Error
MSI (s) (0C:C0) [13:25:59:188]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 2911
DEBUG: Error 2911: Could not remove the folder C:\Program Files (x86)\DealingWithThisWixBullshitInstaller\.
MSI (s) (0C:C0) [13:25:59:190]: Note: 1: 2318 2:
MSI (s) (0C:C0) [13:25:59:191]: Note: 1: 2327 2: 32 3: C:\Program Files (x86)\DealingWithThisWixBullshitInstaller\
MSI (s) (0C:C0) [13:25:59:191]: Note: 1: 2205 2: 3: Error
MSI (s) (0C:C0) [13:25:59:191]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 2911
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2911. The arguments are: C:\Program Files (x86)\DealingWithThisWixBullshitInstaller\, ,
DEBUG: Error 2911: Could not remove the folder C:\Program Files (x86)\DealingWithThisWixBullshitInstaller\.
, , , . . ?
wxs MCVE ( , ):
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
<Product Id="*"
Name="DealingWithThisWixBullshitInstaller"
Language="1033"
Version="1.0.0.0"
Manufacturer="Derp"
UpgradeCode="1408102b-2ffd-41ff-ad57-6319b7fbfa58">
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine"
InstallPrivileges="elevated" />
<MajorUpgrade DowngradeErrorMessage="A newer version of this product is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature"
Title="DealingWithThisWixBullshitInstaller"
Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Property Id="WixShellExecTarget"
Value="[#DealingWithThisWixBullshitExecutable]" />
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Impersonate="yes" />
<CustomAction Id="AddHttpsReservation"
Directory="INSTALLFOLDER"
ExeCommand="[SystemFolder]netsh http add urlacl url=https://127.0.0.1:9998/ sddl=D:(A;;GX;;;BU)"
Execute="deferred"
Impersonate="no"
Return="asyncWait" />
<CustomAction Id="AddHttpsBinding"
Directory="INSTALLFOLDER"
ExeCommand="[SystemFolder]netsh http add sslcert ipport=0.0.0.0:9998 certhash=E68AA1985440FDAD0BB07547BE2C9957F416709B appid={8feef448-1a4f-408f-b6d4-8a90300517ed}"
Execute="deferred"
Impersonate="no"
Return="asyncWait" />
<CustomAction Id="DeleteHttpsReservation"
Directory="INSTALLFOLDER"
ExeCommand="[SystemFolder]netsh http delete urlacl url=https://127.0.0.1:9998/"
Execute="deferred"
Impersonate="no"
Return="asyncWait" />
<CustomAction Id="DeleteHttpsBinding"
Directory="INSTALLFOLDER"
ExeCommand="[SystemFolder]netsh http delete sslcert ipport=0.0.0.0:9998"
Execute="deferred"
Impersonate="no"
Return="asyncWait" />
<InstallExecuteSequence>
<Custom Action="LaunchApplication"
After="InstallFinalize">NOT REMOVE~="ALL"</Custom>
<Custom Action="AddHttpsBinding"
Before="InstallFinalize">Not Installed</Custom>
<Custom Action="AddHttpsReservation"
Before="InstallFinalize">Not Installed</Custom>
<Custom Action="DeleteHttpsReservation"
After="InstallInitialize">REMOVE~="ALL"</Custom>
<Custom Action="DeleteHttpsBinding"
After="InstallInitialize">REMOVE~="ALL"</Custom>
</InstallExecuteSequence>
</Product>
<Fragment>
<Directory Id="TARGETDIR"
Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER"
Name="DealingWithThisWixBullshitInstaller" />
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder"
Name="DealingWithThisWixBullshit"/>
</Directory>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut"
Guid="*">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="DealingWithThisWixBullshit"
Description="Dealing with this wix bullshit"
Target="[#DealingWithThisWixBullshitExecutable]"
WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
<RemoveFolder Id="CleanUpShortCut"
Directory="ApplicationProgramsFolder"
On="uninstall"/>
<RegistryValue Root="HKCU"
Key="Software\Microsoft\DealingWithThisWixBullshit"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<Binary Id="CACert"
SourceFile="muhfakecert.pfx"/>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents"
Directory="INSTALLFOLDER">
<Component Id="ProductComponent">
<File Id="DealingWithThisWixBullshitExecutable"
Vital="yes"
Source="$(var.DealingWithThisWixBullshit.TargetDir)DealingWithThisWixBullshit.exe"
Checksum="yes" >
</File>
<File Id="readme"
Source="$(var.DealingWithThisWixBullshit.TargetDir)readme.txt"
Checksum="yes" >
</File>
<iis:Certificate Id="CACert"
Name="CACert"
Overwrite="yes"
StoreLocation="localMachine"
StoreName="my"
PFXPassword="I HATE YOUR FACE AND I HOPE YOU DIE!"
BinaryKey="CACert"/>
</Component>
<ComponentRef Id="ApplicationShortcut"/>
</ComponentGroup>
</Fragment>
</Wix>