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.
Related
I've a question aboud a custom action that needs to take place during an uninstall. currently I have the custom action working for the biggest part, however there is a small problem.
The custom action needs to take place immediately after the uninstall option is selected since it contains the command to force the running program( installed with the same installer) to close and some other commands for other tasks. bud currently the WIX installer tries to close the program by itself which it is unable to. that means my custom action as well as the rest of the uninstall will fail.
currently I have this code bud it is not working at the point I would like it to.
<CustomAction
Id="UninstallScript"
Directory="INSTALLFOLDER"
ExeCommand="[INSTALLFOLDER]De-installation script.exe"
Execute="commit"
Return="check">
</CustomAction>
<InstallExecuteSequence>
<Custom Action="UninstallScript" Before="InstallInitialize"> Installed AND NOT UPGRADINGPRODUCTCODE AND NOT REINSTALL </Custom>
</InstallExecuteSequence>
any idea how I can make it work the way I intended?
note: if I manually close the running program and then run the uninstall option it works fine. which means the timing of my function needs to be moved forward. also the running program starts when Windows boots up which means it won't show the desktop bud directly shows the program ( this is intentionally ).
thanks in advance,
I have a bootstrapper (C# windows forms applications) that trigger two different msi files consecutively out of its resource. The instance transforms between the msi are 'paired' such that one instance transform from the first msi shares an UpgradeCode with one instance tranform from the second msi; these are the pairs that are installed together via the bootstrapper.
The 'core' msi (the first msi that runs) includes the MajorUpgrade element such that when a higher-versioned 'core' msi is run, all related products with a lower version are first uninstalled - this includes the secondary program installed via the second msi since it uses the same UpgradeCode and is recognized as a related product. This is the behaviour I want so that's good, but if I uninstall the 'core' msi program manually via the control panel, it only installs that one. I'd like to get it to uninstall the secondary program as well, even if I manually uninstall the 'core' one.
Do I need to write a custom function that manually calls the uninstall of the secondary msi's program with the ProductCode? E.g., as per here:
Wix - uninstall different product
Or, can I explicitly schedule RemoveExistingProducts to be run for uninstalls? Something like:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize">REMOVE</RemoveExistingProducts>
</InstallExecuteSequence>
Is that not possible because after InstallFinalize of the 'core' msi, it knows nothing about the secondary msi? Basically, I'm wondering if I can also use the RemoveExistingProducts standard action for the manual uninstall the case, like it's doing for the MajorUpgrade case.
Thanks so much in advance.
Unfortunately, the answer is no.
RemoveExistingProducts does not trigger during a maintenance operation.
You will certain lines in the log file which indicate that:
Skipping RemoveExistingProducts action: current configuration is maintenance mode or an uninstall
What you are trying to do is usually achieved by making use of a bootstrapper application.
Have you explored the bootstrapping feature of Wix called Burn?
Burn should be able to easily handle your requirement.
If using Burn is not an option for you, then i dont see any other option other than writing your own custom code to achieve this.
Hope this helps.
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.
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.
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-->