WiX CustomAction ExeCommand failing

windows-installerwixwix3wix3.5

I have a command line I want to run during the install of a merge module (created by WiX) with the below code.

<CustomAction
    Id='SetWebsiteProtocols'
    Execute='commit'
    Return='ignore'
    Impersonate="yes"
    FileKey='Web.config'
    ExeCommand='c:\windows\system32\inetsrv\appcmd.exe set app "Default Web Site/My Website" /enabledProtocols:http,net.tcp,net.pipe' />

<InstallExecuteSequence>
    <Custom Action="SetWebsiteProtocols" After="InstallFiles"/>
</InstallExecuteSequence>

When I run the command on the command line (hard coded at the moment) it works fine. However, when run during an install, it fails. Turning on logging shows the error code 1721, but googling that returns nothing of interest.

How do I fix this problem?

Best Answer

I see many issues with your code.

  1. You are scheduled for commit which will not be processed if rollback is disabled by policy.

  2. You are impersonating the UAC which may fail in UAC/Elevated situations if your consuming MSI isn't bootstrapped by a setup.exe that is elevating the UI/Execute process.

  3. You have hardcoded a path to the system32 folder which either might not exist because WINDOWS doesn't have to be called WINDOWS or might be the 32-bit or 64-bit system folder depending on OS platform.

  4. You are ignoring the return code so if this fails your install will keep going. Plug and pray anyone?

  5. You will have a big ugly flashing black console window during the install that just screams 'oh this guy didn't know what he was doing.'

  6. You will get absolutely no logging out of the EXE.

  7. You probably aren't aware of the problems that can occur directly calling an EXE custom action.

Here's some reading to help you understand these concerns:

Now I would also mention that you are possibly reinventing the wheel, but it seems that WiX's built-in IIS custom actions don't expose the variation point you need. That's a shame. So I would suggest looking at the following feature to fix up your EXE call:

I find this is a very elegant way of calling your EXE without a flashing DOS box, proper logging into your MSI log and a fix many of Microsoft's EXE concerns. From there you just need to fix it so you are properly resolving the correct 32-bit or 64-bit appcmd. My installers only target Server 2008 R2 which is a 64-bit only platform so my code looks like this:

(This code augments something InstallShield doesn't expose... )

<CustomAction Id="SetIISAuthCAD"
              Property="SetIISAuth"
              Value="&quot;[System64Folder]inetsrv\appcmd.exe&quot; set config &quot;Default Web Site/MyApplication&quot; /section:system.webServer/security/authentication/windowsAuthentication /useAppPoolCredentials:true /commit:MACHINE/WEBROOT/APPHOST " />
<CustomAction Id="SetIISAuth"
              BinaryKey="WixCA"
              DllEntry="CAQuietExec64"
              Execute="deferred"
              Return="ignore"
              Impersonate="no" />
<InstallExecuteSequence>
    <Custom Action="SetIISAuth"
            Before="InstallFinalize">Not Installed</Custom>
    <Custom Action="SetIISAuthCAD"
            Before="SetIISAuth">Not Installed</Custom>
</InstallExecuteSequence>
Related Topic