I have another question regarding exe's and custom actions within Installshield.
I currently have a set of custom actions which launch executables in silent mode..
In the return process, it is set for Synchronous(Check exit code) mode, and it is set for a Deferred Execution in System Context.
My question is the following:
When I install my application, it is fine. It runs through the installers and installs the prerequisites. My problem is when I want to uninstall the application from the machine, because it runs through the same installers again (and trys to install them again, even though we are uninstalling).
I looked all around, and cannot find a good work-around for this.
Anyone have experience with this and know of a method of getting the installs to only run when the installer runs and not when uninstalling?
Much Appreciated...
Thanks
-Kyle
You have to condition your CustomAction to "Not Installed". The condition "Not Installed" ensures the action runs only during a first-time installation, and not during maintenance mode or uninstallation.
Check this link from Flexera: http://www.flexerasoftware.com/webdocuments/PDF/IS_Tip_Executable-Custom-Actions-for-MSIs.pdf
How about a custom action condition like "Not Installed". This means it will only run on a first-time installation, not "maintenance" or "uninstall".
Related
I have created MSI using WIX 3.11. I have made some customization to the Installer to install the application in a custom folder. I am also writing Install path to registry value under HKLM\Software.
I am reading registry value in batch file for one of my use-case.
Installation is successful and the application is running fine.
But while uninstalling, I am facing below issue -
Uninstall window pops up with the message - The following applications should be closed before continuing the Install: [MyApplication]
In uninstall log while removing the service, I see below error - Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor.
If I remove the service manually, no errors can be seen and the service is getting deleted. Not sure why Uninstall is failing.
Please shed some light on this.
Stop Service Before Uninstall: In the compiled MSI, what entries do you have in the ServiceControl table? You need to stop the service before its executable is deleted. See WiX service installation sample linked to below.
Failing Custom Action: It is also possible that you have a custom action which tries to run a batch file that has already been uninstalled when you try to run it. This can be a custom action that should not run on uninstall (conditioning is wrong), or you have sequenced it incorrectly so the batch file is gone from disk - courtesy of the uninstall - before the custom action can run successfully. You need to move the custom action earlier in the installation / un-installation sequence or condition it better so it never runs on uninstall. Both issues are very common. Be aware that it is common to fail to condition custom actions so they run unexpectedly. Very often they run during major upgrade uninstalls undesirably.
Batch Files CAs: For what it is worth - and no offense: using batch files in custom action is an MSI anti-pattern in my opinion. There is basically zero error handling and hence no management and recovery from error conditions. And generally no MSI rollback support. C++ custom actions are best in my view (minimal dependencies, good debugability, full featured language, large down-to-the-metal API). Just so it is mentioned. It all depends how large your distribution is. For in-house appliations one can get away with more than for truly global package distribution. This has to do with the complexity of deployment (see section a bit down the page). There are so many error sources.
WiX Service Installation: Maybe see this hands on WiX-markup sample from Rainer Stropek: WiXSamples - github.com/rstropek. Please check
the ServiceControl element.
Common MSI Problems: I hate to "pitch" this content. It is essentially the things you can't easily find in books - and for good reason. Some rules of thumb and opinions in a chaotic form, but here it is if you want to check it out: How do I avoid common design flaws in my WiX / MSI deployment solution? Just honest opinions and practical advice - no claim to be "right", but it should help setup reliability. Hopefully.
On the Wix's document How To: Run the Installed Application After Setup, the condition for the Publish element contains and NOT Installed aside from the property that contains whether the application should be run or not:
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
Why is it there? What does it do?
The custom action pointed to by the Publish element will run only when the whole condition provided evaluates to true.
NOT Installed: is true for fresh installation and major upgrade. Otherwise always false.
WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1: is true when the property is set equal to 1.
So, translating the condition into words: launch the application on fresh install and major upgrade install only when WIXUI_EXITDIALOGOPTIONALCHECKBOX is also set to 1. Otherwise do not launch. Both conditions must be satisfied for launch to happen.
Technically: Installed is essentially checking whether the product GUID of the MSI you are installing is already registered as installed on the system. If it is, then the condition NOT Installed evaluates to true.
Launching Application: Yes, this can be a bit confusing, but it does what it says in the documentation: it makes the application only launch during fresh install and not during repair, modify, uninstall, minor upgrade patch (or other installation modes).
Interestingly it should (as far as I can see) cause the application to launch during an interactive major upgrade as well (Installed is not true for the new setup being installed on top of the old one, but it is true for the uninstalling setup - a major upgrade is essentially and uninstall of the old version and a fresh install of the new version).
So NOT Installed seems to only be true in two cases: fresh install and major upgrade. The two cases where you want to auto-magically launch your application?
Since the InstallUISequence is skipped in silent installation mode, there will be no application launched after a silent install since your dialog will never be encountered (only the InstallExecuteSequence runs).
Digression, similar issue - LaunchCondition: I just commented on almost the same issue the other day in the context of LaunchConditions. If you follow the link, please be sure to read Phil's follow-up comment as well.
To use other words than above: essentially the OR'd Installed condition ensures that the LaunchCondition only applies on fresh installation (or on major upgrade for the new package being installed on top of the old one). This seems to be a nifty feature from the WiX guys - I noticed Installshield does not seem to use this concept. I haven't tested this much, but it seems like a good concept.
Alternatively, as Phil states in the linked comment above, in the context of LaunchConditions you could condition the LaunchConditions actions instead of complicating the actual LaunchConditon condition. Not sure which is better.
UPDATE:
On Conditions In General: MSI conditions can be quite confusing. Here are some resources to work them out:
Installshield Common MSI Conditions Cheat Sheet (from Installshield).
How to execute custom action only in install (not uninstall) (scroll down)
I have one further link that I tend to provide, but it has a number of subtle problems that I want to test out before sending people to the content.
It probably isn't clear from a (seemingly casual) condition such as "not Installed", but there is a set of standard Windows Installer properties, and Installed is one of them:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370905(v=vs.85).aspx
A product is "installed" if its ProductCode is registered as installed on the system. In the context of that WiX source, it means "run only when the product is not already installed".
Conditions are especially important in custom actions. If you don't put any conditions on a custom action then it will run at install time, and also whenever and install-type operation takes place, such as uninstall, repair, applying s patch. Conditions are documented here:
https://msdn.microsoft.com/en-us/library/aa368012(v=vs.85).aspx
The Not Installed condition attempts to ensure that even if WIXUI_EXITDIALOGOPTIONALCHECKBOX is set to 1 by default, the action is only published in scenarios that the exe is strongly likely to be present. Why do this? If someone selects to launch the exe when it's not present, an error message, or a missing UI, could confuse the user. In other parts of the installation process, a failed launch could abort and roll back the installer.
By then why is the condition NOT Installed? That probably sounds backwards to you. But it's not an accident. The Installed property is set at the launch of your installer, and is not updated until the next time it is launched. Even when the installer alters the state by installing or uninstalling the product, the value of Installed is left untouched.
So what are the scenarios where NOT Installed will be true on the ExitDialog?
First-time install:
Installed will start (and remain) false, so at the end NOT Installed will be true. If the installation completes successfully, your exe is probably there. If the installation is cancelled or rolls back, the installer could✱ show a different final dialog that does not offer the launch option.
Maintenance, repair, uninstallation: Installed will start as true, so at completion NOT Installed will be false. This can result in a false negative in, e.g., a repair scenario; the exe may be present but the installer will not try to launch it. But, more importantly, it prevents the attempt to launch the exe after it was just uninstalled.
Upgrades: Depending on the type of upgrade, this will be equivalent to one of the prior scenarios. Minor upgrades and small updates are a form of maintenance, whereas major upgrades act like a first-time install.
Note that this condition may not be foolproof in more complex projects. If your exe is installed only in a subset of your configurations (e.g., if it's installed only by a feature that you can choose to exclude, or by a component that depends on the version of the OS), you may want to enhance the condition or remove the launch action entirely.
✱ I say could show a different dialog because I'm uncertain what WixUI_Minimal does here. If it shows the same dialog, then the condition is insufficient to accomplish what I described here.
I have a custom bootstrapper (C# WPF) and it works well enough. If the installer gets run from the command line after it was installed, it brings up a window allowing the user to select if they want to modify, repair or uninstall. So far so good. Modify mode starts the UI which ends up calling Bootstrapper.Plan(LaunchAction.Modify). The problem is that if I call it from the launcher UI it immediately complains that a prior install requires a reboot.
I have not found any good examples on what this should do. Even the WiX mailing list came up blank.
Any ideas?
It would be helpful with the screenshot for that reboot message - just to get a feel for where it might be coming from and to get a literal string to search for. Did you have a look in the WiX source code yourself btw? (WiX 3.111 branch)
I started writing a lot of stuff about reboots. Not good. Maybe just some questions instead:
Does this happen every time you invoke modify and is it reproducible on more than one computer? Or maybe it is just Windows Update acting up on a problem computer?
I assume you have rebooted the computer where you see the problem and you see the problem again when you re-launch the bundle?
Do you schedule any reboots inside your MSI files during the initial installation?
Either using the ScheduleReboot action or a custom action which schedules a reboot with a call to MsiSetMode (for example)?
There is a long explanation here why such reboot-constructs cause problems, but that may be besides the point. Essentially badly configured reboot-constructs can trigger spontaneous, unexpected reboots without warning when packages are run in silent mode (plus other problems).
Could you try to run the test VBScript found in this answer: WiX behaving badly on XP machine with windows update issues in order to check if the script reports a reboot being necessary?
Other than that I guess you could try to run Burn yourself in debug mode (not sure how much plumbing that would be to get running) or perhaps first try a ProcMon.exe session to see if you can see something obvious. The latter should be quick to do?
There are some registry locations you can hunt down to see if you can figure out what triggered the reboot warning. Get-PendingReboot-Query. And a similar PowerShell script.
So in the end it was user error. :-( O well. I did learn a lot about how to figure out how Windows checks for the need to reboot etc.
The issue was simple in the end. During the modify run it was uninstalling, then reinstalling a number of services. The problem is that when it runs (seeing as you have to set it to repair to get it to work) it copies all the files again and the services were still running at the start of the install. The fix was to uninstall anything that might lock a file before the actual file copy starts and that solved the issue for me.
Thanks for your help guys, all the info helped me look in different directions until I found the issue. Awesome community as always!
The Setup
So I have a Custom Action in my InstallExecuteSequence that looks like this:
<Custom Action="UpdateConfigFile" After="InstallFinalize">NOT Installed OR Upgrading</Custom>
Where Upgrading is defined to:
<SetProperty After="SetFirstInstall" Id="Upgrading" Value="true">
WIX_UPGRADE_DETECTED AND NOT (REMOVE="ALL")
</SetProperty>
The Custom Action updates a web.config file with a value that is passed into the installer via a Property. It is a VB.Net function.
The Issue I'm Running Into
This Custom Action has always executed in many of our installers. But for a certain environment that we have in development, the conditions for it resolve to False on a install/upgrade scenario. It says "(condition is false)" in the MSI log.
The environment is used for development purposes such as testing the product after installed/updated.
What I'm Trying to Accomplish
I would like this to be resolved so that this environment can install our product successfully.
What I've Done So Far
I've installed the same installer to different Operating Systems such as Windows 10, 2012 R2, and 2016. The installer works just fine since the Custom Action runs as expected.
The troublesome environment is a Windows Server 2012 R2 machine. Which makes me even more confused.
I did some digging in and was only able to find this link: (https://blogs.msdn.microsoft.com/heaths/2006/07/11/why-a-custom-action-may-not-run/#comments)
From the link's suggestion, I think it is really odd if a dependency was missing because the same installer works on other machines.
So I'm pretty stumped at this point. Any help or direction would be very much appreciated. If I'm not being clear enough, feel free to ask for more clarification. Please and thank you.
Just some comments to get going, this isn't a real answer:
First things first: in order to be passed properly to deferred mode (InstallExecuteSequence) properties should be UPPERCASE (public properties) and they should be listed in the SecureCustomProperties delimited list of "safe properties" to pass to deferred mode.
Other than uppercasing it, I wouldn't set a property called Upgrading like that, I would rather use the "raw" conditions for the custom action in deferred mode (InstallExecuteSequence).
Here is a cheat sheet of common conditions from Flexera (makers of Installshield): Common MSI Conditions Cheat Sheet. And here is a direct link to the PDF.
You can have a look at this old post: How to add a WiX custom action that happens only on uninstall (via MSI)?. I have never had the time to test all those conditions, but at face value it looks correct.
Some notes about the special property UPGRADINGPRODUCTCODE.
UPGRADE:
Questions:
That Windows Server 2012 R2 machine - is there anything special about it? Is it tightened for security? What is its task or purpose on the network?
What is the actual implementation of UpdateConfigFile - is it a script, a compiled DLL written in C++, a managed DLL written in a .NET language, or something else? Maybe an EXE file?
Does any of this sound familiar: Installer fails on Windows Server 2012 R2
Did you verify that the correct version of the .NET framework is installed on this problem server? Does the function run interactively? Try running that VB.NET function interactively on that computer via a test harness EXE if it is a DLL function. Or just run it straight is it is an EXE file outright.
The issue is likely to be that you are scheduled after InstallFinalize (which is not good, see later) because the Upgrading property is not public (not uppercase). If you change the condition to WIX_UPGRADE_DETECTED AND NOT (REMOVE="ALL") it should work, assuming:
WIX_UPGRADE_DETECTED is the actual property associated with the major upgrade, such as from the major uypgrade element.
WIX_UPGRADE_DETECTED is in SecureCustomProperies.
Actions after InstallFinalize are generally not recommended because if they fail (in your case screw up the config file) then there is not much that can be done (such as roll back to a correct config file). It's effectively after the install, so it's also easier to do the config changes in the app when the upgraded version runs for the first time.
After helping the team responsible for the environment, we found out that it was a certain scenario that was causing this issue. Digging deep into the MSI log further, we found that a previous Custom Action running, also after InstallFinalize, was returning a Failure Action Result. Since that happened, the following Custom Actions such as my UpdateConfigFile Custom Action, don't execute. Resulting in the "(condition is false)" entry in the log.
Once we figured that out, I was able to reproduce it on my local environment.
Since these Custom Actions are after InstallFinalize, I thought that those Custom Actions would still run if one failed because we're past the point of the installer being able to do a Rollback. But I was wrong and now I know.
Thanks for everyone helping me out in trying to figure out this issue. I was getting worried that I was going to try to figure this out for days and start pulling my hair out. XD
If the application is running and user tries to uninstall the application then it doesn't give an option to close the application like it use to give for normal wix. This problem has occurred only after I moved to bundle project. Any step to be performed?
Earlier it use to give The following application should be closed before continuing the install:
There are a few things to look at:
If your bundle uninstalls the MSI product completely silently then the uninstall will obey that rule and will not offer any files-in-use dialogs.
Windows Installer sometimes decides not to force the user to shut down the app if it can be process isolated and cleaned up when the user finishes.
A verbose log will give more detail.
WiX has the CloseApp help for closing down apps, and integrating the app with Restart Manager can also help these situations.