How to execute Wix custom action after installation? - wix

I am using Wix3 to install WCF service to IIS.
How can I use my custom action (c#) function after installation completed? i.e. I need to open installed web.config file and replace hostname with real one.
Any ideas?

You can schedule it after InstallFinalize action in InstallExecuteSequence.

There is a sequence of Actions in Windows Installer. The WiX tutorial has a good section on events (and is a great resource anyway).
A typical example of getting something to run after InstallFinalize is to get the installed app to start.
<InstallExecuteSequence>
<Custom Action='LaunchFile' After='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>

Why would you:
1) Need a custom action?
2) Do it after the install instead of during the install?
WiX has a built-in extension for handling what you are trying to do:
XmlFile Element (Util Extension)
It will update your XML after the file has been installed and handle rollback scenarios as well.
What you will have to write a CA for though is reading the XML value back into a property ti handle repair and upgrade situations. Read:
The WiX toolset's "Remember Property" pattern.

Related

Run custom action of uninstalled application

When performing an installation while there is already another version installed, we need to call a custom action that makes use of an exe of the old application (prior to it being removed). The custom action is responsible for removing an old scheduled task. How would one go about doing such a thing?
You can implement this in the upgrading installer.
The basic idea is you have a deferred custom action which will run only when WIX_UPGRADE_DETECTED property exists. This is set when you use the <MajorUpgrade> wix element in your product for upgrades. Then you can schedule your custom action before RemoveExistingProducts and it will be able to remove the scheduled task.
There are some caveats to this approach.
The first caveat is that this approach limits where you can schedule RemoveExistingProducts. You must schedule "afterInstallInitialize" or later.
If you do use "afterInstallInitialize" then scheduling your custom action Before="RemoveExistingProducts" will be fine. If you schedule RemoveExistingProducts later on in the install process you will probably need to shcedule your custom action Before="InstallFiles" in case the old exe or a file it might load is replaced by the new install.
A basic implementation of this might look something like this
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A newer version of [ProductName] is already installed."/>
<CustomAction Id="CA_RemoveScheduledTask" BinaryKey="CustomActionsDLL" DllEntry="RemoveScheduledTask" Execute="deferred" Return="check" />
<InstallExecuteSequence>
<Custom Action="CA_RemoveScheduledTask" Before="RemoveExistingProducts">WIX_UPGRADE_DETECTED</Custom>
</InstallExecuteSequence>
You may also need to pass in the install location to the custom action which can be access using the session's CustomActionData property. An example of how to do this can be seen here. This is just so you have the correct path for the exe location. Usually I get the install path via a registry key search.
There are at least two approaches that could be used longer term, because it's not normal to want to run a custom in another installed product.
If this executable is needed in both installs then it's a shared resource, and the executable and the custom action could be common to both installs (perhaps in a merge module to keep sharing properly).
It seems that the condition on calling the custom action in the older install might be incorrect if it's supposed to be called sometime during an upgrade or uninstall. For example, if it should be called when it's being uninstalled as part of an upgrade then condition the call on UPGRADINGPRODUCTCODE.

Launch Firebird 1.5 installer from WIX

I have been tasked with writing a WIX installer from an application that uses Firebird 1.5. The WIX install process must launch the firebird installer if firebird has not already been installed. Using a custom action I get the firebird installer to launch but end up with error "1607 unable to install installshield scripting runtime". I have searched this error but have not been able to find a resolution.
Here is a snipit of my custom action.
<InstallExecuteSequence>
<Custom Action='LaunchFirebirdsetup' Before='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
<CustomAction Id='LaunchFirebirdsetup' FileKey='Firebird15Setup' ExeCommand='' Return="ignore" Execute="commit" Impersonate="no" />
It might be because you cannot run an MSI install from within an MSI install, I think that's still true even with a Commit custom action. Your IS Script install is an MSI install, so that may be the issue. Launching installs from within installs is always an issue. You should use Burn to launch that Firebird install before installing yours. That's what a Burn bundle is for - prerequsites and associated installs as well as your MSI setup. You could use it to install a standalone ISScript MSI, that's another possibility.
The other issue is that some installs just don't work when installed with no impersonation, which means with the system account. There's no indication that you tried to do it silently, which means that it's running with the system account and may attempt to show UI to the interactive user, and that will fail. This another reason to install it with Burn - it will run as the interactive user.
Looks like bootstrapping (burn) is the solution.
Took me a while to get it but after getting it to run, it makes sense I guess.
Instead of running an installer exe you could use merge modules. For instance the Firebird 1.5 Merge Modules from MWA Software. Modules, installation instruction and source for the merge modules are freely available.

How to get rid of the "files in use" dialog during uninstall?

I'm very new to WIX and am using the minimal GUI to install and uninstall a dll. This dll gets registered as a service in a custom install script that I am calling upon install.
Upon uninstall, I stop and unregister the service in a custom script.
My problem is, before the custom uninstall script is called, I get the files in use dialog box as the dll is being used by the service. I want to avoid this, as I know I will be stopping the service in the custom uninstall action.
Any easy solutions to this problem ?
Thanks!
Nikhil.
Are you using a Custom Action to stop the service? If so I'd make sure that your custom action is run before the removal of your file
i.e.
<CustomAction Id="StopService" Directory="DirMyService" ExeCommand="NET STOP ServiceName" />
<CustomAction Id="StartService" Directory="DirMyService" ExeCommand="NET START ServiceName" />
<InstallExecuteSequence>
<Custom Action="StopService" After="InstallInitialize">Installed</Custom>
<Custom Action="StartService" Before="InstallFinalize">Installed</Custom>
</InstallExecuteSequence>
Haven't tested this, so you may need to stick in the windir before the net stop etc, and those might be the wrong places to put it in to stop/start the scripts. But might give you an idea of how to solve your problem.

WIX MSI customaction not running when deployed using Group Policy

I'm using WIX to create an MSI which has a custom action to install a clickonce application. I want to deploy the MSI via GPO. The custom action runs fine when I just double click to run the msi, but the custom action does not seems to be running when deployed via GPO. But if you look at the add/remove programs in the control panel you have the product/msi listed there as if it was successfully installed.
To see if custom actions work at all when deploying via GPO I created a simple custom action which just writes a file to c:\temp (existing) folder. Added the custom action to both InstallExecuteSequence and AdminExecuteSequence in before installfinalize step. Tried both deffered execute and immediate execute. It works when you double click the msi to install but not via GPO.
Is it possible to have custom actions when the msi is deployed through GPO? Are there any limitations? Is there anything special that I need to do to get it to work with GPO?
Thanks in advance!
Rukshan
I figured it out. The issue was that I hadn't configured the GPO to install the package when the user logs in. After checking that check box in the group policy properties it works.
If you assign the software to users and do not check "install this application at logon", the application will be listed on the user's add/remove programs panel but doesn't really install it. So I was under the impression that it was successfully installed without running the custom action when it really wasn't installed.
Now I have my custom action listed under Install Execute sequence
<InstallExecuteSequence>
<Custom Before='InstallFinalize' Action='ClickOnceIntallCustomAction' >NOT REMOVE</Custom>
</InstallExecuteSequence>
And it is set to execute immediately and check on return
<CustomAction Id="ClickOnceIntallCustomAction" BinaryKey="ClickOnceInstallBinary" Return="check" Execute="immediate" DllEntry="Test" ></CustomAction>

Stopping display of custom dialog boxes in WiX uninstall

I have a WiX installer project that utilises a custom dialog box to ask for parameters to update a web.config file and run a database script on install. Everything works correctly and the application is installed and runs correctly.
However, the custom dialog box is also displayed when I uninstall the software and it certainly doesn't need to be (as I'm not updating a web.config file).
Is there a way to suppress the custom dialog when the application is being uninstalled?
(I should also remove the sql procs I install, at uninstall time but that is outside of this issue).
The solution to your question is to condition the custom action with the condition (Not REMOVE="ALL"). This will make the action run on fresh install and maintenance install, but not on uninstall. If you don't need to run on maintenance install, but only on a fresh install you can set the condition to be: (Not Installed AND Not(REMOVE="ALL")). Full list of MSI properties and brief descriptions here: http://msdn.microsoft.com/en-us/library/aa370905(VS.85).aspx.
The sequencing and custom action logic in MSI files is VERY complicated. It really pays off to avoid custom actions whenever you can.
There is more - all MSI files have built-in support for silent installation. This means that the entire GUI sequence can be skipped, and the MSI file installed without user interaction. This is a crucial feature for corporate deployment via SMS / SCCM or other deployment mechanisms. Showing a custom dialog box when the setup is run in silent mode is a violation of this basic MSI feature. You can work around this by properly conditioning the display of the dialog based on the property UILevel: http://msdn.microsoft.com/en-us/library/aa372096(VS.85).aspx. Just to keep things interesting and confusing Microsoft has defined 4 levels of GUI during an installation ranging from completely silent, through various options such as progress bar only etc... See the link for details.
I could add a lot of details here about MSI sequences, conditions, custom actions and similar, but it wouldn't answer your question. Please add any follow-up questions.
Wix snippet to show the creation of a custom action and its insertion into the InstallExecuteSequence:
<!--Custom Action Sample Section-->
<Binary Id='VBScriptCustomAction.vbs' SourceFile='VBScriptCustomAction.vbs'/>
<CustomAction Id='test' BinaryKey='VBScriptCustomAction.vbs' VBScriptCall='Hello' Return='ignore'/>
<InstallExecuteSequence>
<Custom Action="test" Sequence='4111'><![CDATA[NOT REMOVE~="ALL"]]></Custom>
</InstallExecuteSequence>
<!-- End of Custom Action Sample Section-->