I created an installer based upon the code I found here. If a previous version of the app exists, I want the installer to delete it before installing the new one.
If it's a clean install, everything goes well.
If it's an upgrade, a weird thing happens. As expected, the old version is removed, the registry is changed, and shortcuts are placed on the desktop. Oddly, the primary file doesn't exist in the application folder when the installer completes.
Upon launch after an upgrade, a small installer message box pops up and states "Please wait while Windows configures -app name-..". After this quick message, the file exists as it should in the app folder, and the app launches.
Prior to launch though, it's not there. I even tried a reboot before launching the app to see if that would place the file if it's stuck in a some kind of cache.
Anyone ever see this behavior? It's a bit like this questiom, but it happens on every upgrade.
Oddly, the primary file doesn't exist in the application folder when the installer completes.
This is a common problem with windows installer upgrades if components are not managed correctly. You'll typically see that the missing file re-appears if you launch the installer into maintenance mode from the control panel and do a "repair". In this case, windows repaired the application automatically when you launched it.
A few possible explanations of the top of my head:
the new version of your installer installs this file in a component with a new GUID. This causes problems because Component GUIDs should remain stable.
your installer installs multiple files per component. This causes problems because whether a component should be installed is determined by the keypath, and only one file can be the keypath. Stick to one file per component.
The "new version" of the file actually has a lower version number. Such an "upgrade" doesn't work correctly.
Related
I'm working on an MSI installer written in Wix. The installer works in both per-user, and per-machine contexts.
In a per-machine installation, everything goes smoothly; the product is installed and configured for the initial user. Upon switching to a test user, the application appears in the start menu correctly. Running it for the first time, a msiexec process starts with the message that the app is being configured. However, if the original .msi has been deleted, this process fails.
The failing setup action gives the following message in its log:
Error 1706. An installation package for the product myProduct cannot be found. Try the installation again using a valid copy of the installation package 'myInstaller.msi'.
=== Logging stopped: 3/16/2017 11:15:52 ===
I understand from reading a blog post by Rob Mensching (Lead of Wix) that it probably isn't possible to just edit the source list to point towards the windows cached .msi, a point backed up by another article I've found. Is that correct?
Is there a way to stop this entire action of calling the msi on first run by users from happening? Caching the msi or keeping the original is not ideal, I'd like to use the .msi in a custom bootstrapper that involves deleting the msi once installation is complete.
Microsoft recommends you keep the original MSI available, Rule 31:
https://blogs.msdn.microsoft.com/windows_installer_team/2006/05/24/tao-of-the-windows-installer-part-3/
and I won't repeat what it says about repair/resiliency, but you cannot guarantee the source MSI won't be needed sometime.
You're probably getting this "repair" because there is some resource (a file most likely) that is being installed to a user-profile location. When another user logs on and uses the application that file is missing, so potentially the application is broken. For example a file installed to User's Application Data needs to be available for all users of the system, not just the user that installed it.
So keeping the MSI might not be ideal but is strongly recommended, and in your case of product use by multiple users it's even more likely to required. There should be an Application Event log entry under MsiInstaller that says something about the missing resource.
I'm trying to certify a desktop application for Windows 8.1 using Windows App Certification Kit 3.1.
Everything is fine with the exception of the uninstall. I created the MSI file using Wix Toolkit 3.6. When the application installs it creates an entry in Programs and Features as well as a shortcut for uninstalling.
When I trigger the uninstall from either of these locations it works properly and all the files and registry entries get removed.
However, when the WACK launches the uninstall process, the MSI starts the installation process instead.
Is there a specific command from msiexec I need to test that WACK might be using to cause this?
I really do not understand why the Kit will launch the installer again.
Thank you,
Fernando
I found the problem and my solution.
The WACK calls the uninstall process using the Change option instead of Uninstall. You can test this by going to *Programs and Feature*s and clicking Change.
Since my application does not support changing or repairing, I simply set ARPNOREPAIR and ARPNOMODIFY to "Yes" and now WACK only calls uninstall.
The other option is to offer the Change/Repair dialog on your setup project and have the Remove check-mark available.
Hope this helps.
Cheers,
Fernando
My Wix installer worked installing my program, but it's broken for uninstallation. A file is removed too early, and it's needed further down the line. The uninstaller fails and reverts its changes.
This means I can't remove the package from my machine, and hence can't install any further builds of my installer (a considerable inconvenience). How can I force removal of the package?
Update, Stein Åsmul: Injecting this newer list of cleanup approaches.
Find your package in C:\Windows\Installer, where Windows keeps copies of installed MSI packages. The names are generated randomly, so you'll have to look at the creation dates of the files.
Open the MSI file with Orca. (Unfortunately there is no simple download for the orca installer. You can get it by installing the "MSI Tools" of the Windows 10 SDK, and then searching for orca.msi in C:\Program Files (x86)\Windows Kits.)
Delete the offending custom action from the CustomAction table
Now you should be able to uninstall the package.
UPDATE: You can find the actual cache MSI file using Powershell. That was for one package, you can also get for all packages (scroll down to first screenshot).
This command usually works for me:
msiexec /fv installer.msi
It somewhat recaches the installer, so you can try again with a corrected one.
One time this command didn't work and I had to use Microsoft FixIt. It solved the problem (quite a shock for me).
Depending on the exact reason of the behavior you described, you might have at least a couple of options.
If the reason of the failure is a custom action which runs on uninstall, and this custom action is conditioned with some properties you can influence upon, you can try to pass the desired value via the command line:
msiexec /x {YOUR-PRODUCTCODE-HERE} RUNMYACTION=false
In this sample RUNMYACTION is a Windows Installer property which participates in a custom action condition, and if you pass false as its value, the action won't run.
Otherwise, you can fix the logic (or just disable the custom action explicitly) and build the new MSI package. Then upload it to that target machine, and run like this:
msiexec /i YourPackage.msi REINSTALL=ALL REINSTALLMODE=vomus
Here YourPackage.msi is a new fixed package, REINSTALL=ALL instructs the msiexec to re-install the product using this new package, and REINSTALLMODE=vomus (the v part of it) will re-cache the MSI package and you'll be able to remove it the normal way afterwards.
A side note: you should test your installation on a virtual machine in order not to risk your real one.
FYI: In Windows 8.1 the installers have been moved here: C:\ProgramData\Package Cache\
If you are really desperate and all solutions above don't work try
msizap.exe
This will erase all that your installer put on a machine
LITTLE WARNING
Don't run msizap without knowing what options you want to run it with (for a list of options run msizap /? first).
I used this little tool also from Microsoft
https://support.microsoft.com/en-us/help/17588/fix-problems-that-block-programs-from-being-installed-or-removed
Basically this tool can be used to "repair issues including corrupted registry keys that block you from installing or removing programs"
What it fixes:
Corrupted registry keys on 64-bit operating systems
Corrupted registry keys that control the update data
Problems that prevent new programs from being installed
Problems that prevent existing programs from being completely uninstalled or updated
Problems that block you from uninstalling a program through Add or Remove Programs (or Programs and Features) in Control Panel
It can be used for:
Windows 7
Windows 8
Windows 8.1
Windows 10
I usually just look for <Your Installer's Name>.msi or <Your Installer's Company Name> in the registry and delete some of the uninstall keys from some of the Products under the Windows installer trees and everything usually works fine and dandy afterwards, although this WOULD leave some stuff lying around like cached installers and possibly tons of other registry keys for each file installed, etc. but its ALWAYS worked for me when developing installers because honestly, who cares if one MSI is left over and cached somewhere? You're using the machine for development anyways, right?
I've developed a Wix installer for an internal project however entirely by accident I've found that I'm unable to uninstall the installer on my development machine as I get the following error message:
The feature you are trying to use is on a network resource that is unavailable
with a dialog pointing to the path of the .msi that I installed from feature from. (The .msi is there, however is has been rebuilt and so has changed since I installed it)
I'm concerned by this dialog as I had believed that Windows Installer kept track of installed .MSI files, however this dialog seems to suggest that I can break my uninstaller by deleting, moving or changing the installer.
Is this the case?
What do I need to do to make sure that I don't break my uninstaller in this way? (Do we need to keep copies of all versions of the installer ever installed on a machine?)
The easiest way to get out of this situation is to do a recache/reinstall. Build a new version of your MSI that isn't "broken" (in whatever way it is broken, in this case, it might not really be broken at all, you just need a new source). Then you use a command line like:
msiexec /fv path\to\your.msi /l*v i.txt
That will copy your.msi over the MSI that is cached and do a repair. Then you'll be in a better place.
One of the first painful lessons of writing installs is to never run your install on your own box. Certainly not until it reaches a point of maturity and has gone through several QA cycles. This is what we have integration labs and virtual machines for. (There is a saying about things you shouldn't do in your own back yard.)
That said, normally an MSI uninstall doesn't require the MSI but there are situations where it could be required. For example if one was to call the ResolveSource action during an uninstall, MSI would then look for the .MSI.
Now there are several ways out of this pickle:
Take an MSI you do have and edit it with ORCA to match to file name, UpgradeCode, ProductCode and PackageCode of the MSI that you installed. You should be able to get all of this information from looking at the stripped cached MSI that exists in %WINDIR%\Installer. CD to that directory and do a findstr -i -m SOMESTRING *.msi where SOMESTRING is something unique like your ProductName property. Once you know the name of the cached MSI, open it in Orca to get the required attributes. Then put these attributes in a copy of the MSI you have available and try to do an uninstall. No, it's not the exact MSI that you installed but usually it's close enough.
or
Use the front end windows installer cleanup utility (if you still have it) and/or the backend MSIZAP utility to wipe all knowledge of the application from MSI and Add/RemovePrograms. Note, this doesn't actually uninstall the program so you'll have to also write a script or otherwise manually uninstall all traces of the program.
or
Reimage your workstation
If you know exactly what is wrong (which is often the case during development), I prefer to open the MSI file that Windows will use for uninstallation and edit it directly with a tool like Orca to fix or remove the part that causes the failure.
For example:
Locate the MSI file in %WINDIR%\Installer. The MSI should be the last edited MSI file in that folder right after you did the failed uninstallation.
Open the msi file with Orca.
Remove the failing part - for example the InstallExecuteSequence action that fails which is atypical scenario.
Save the msi and close Orca to release the lock on the msi file.
1 - Have you experimented with "run from source" during installation?
This is an option in the feature tree which allows you to run some files from their installation source. This is generally combined with an admin image on the network. See image below. I haven't tried it, but I assume this could cause: "The feature you are trying to use is on a network resource that is unavailable" if the network is down and you are trying to uninstall. Just a theory, there are other ways this could happen.
2 - Are you running script custom actions? If so, do you extract to the tmp folder or run from installed files or the binary table? If so, is the custom action conditioned to run only on install?
3 - Are you perhaps running an EXE custom action that is pointing to an installed file? If so this file may be unreachable on the network.
4 - Are any of your userprofile folders redirected to a network share?
5 - Are you installing anything directly to a folder on the network?
There are plenty of other possibilities.
I've created a WiX setup project based on the article WiX 3 Tutorial: Understanding main WXS and WXI file mainly because it gives the WiX needed to do an application shutdown.
However, I'm puzzled by the outcome. Here's the situation:
We have an executable which uses a dll and create a setup which installs the executable and the dll. We execute the setup.
CASE 1: Next, we change the executable and NOT the dll and create the setup again. Then we start the installed application and make sure also the dll is loaded. If we now execute the second setup, a dialog is shown asking the user to shutdown the executable just as we expected.
CASE 2: But if we do not change the application but only the dll and then execute the setup while the application is running and the dll is loaded, no dialog is shown. At the end of the setup a dialog appears asking if we want to restart the computer.
Is this expected behaviour and how can I force the application shutdown dialog of CASE 1 also when only a dll is changed as in CASE 2? I do not want the user having to restart the computer because the application is running on a server which cannot be restarted.
This is all determined by Windows Installer during the costing process. The installer decides which files need to be installed / updated and calculates how much disk space is needed and if there are any file locks. If there are file locks, it attempts to resolve the lock to a process with a window handle. If it can do this, you'll get the dialog. If it can't, you won't. This doesn't mean a reboot won't be needed, it just can't give you useful information on how to avoid it.
A few additional points:
Make sure you are versioning your EXE and DLL. If the old DLL is 1.0.0.0 and the new DLL is 1.0.0.0 costing will say "Nothing to do here".
How does the EXE use the DLL at runtime? It might simply not have a lock on it during the entire life of the process.
Understand that MSI's reboot behavior can be altered through the use of properties such as REBOOT=ReallySuppress
Here's some good articles to read:
InstallValidate
FileInUseDialog
System Reboots
I haven't checked the code but I think what is happening is the CloseApplication action is not running because it sees that the exe hasn't changed. As far as I am aware you cannot target a DLL with CloseApplication. If you run your install with logging you should be able to see if the action is triggered. I am assuming you have RemoveExistingProducts schedule late in the install, if you were to move it after InstallValidate it would remove the exe every time and therefore trigger the action.