wix toolset - burn - no necessary admin rights for updates - wix

I have a wix bundle (with managed bootstrapper) consisting of
4 ExePackages (3rd party setups - all perMachine)
1 MsiPackage (our application setup)
Since we update our application multiple times a month, we don't want the user to need admin rights for every update. Usually just our application needs to be updated, because 3rd parties are changing very rarely (on update process they get skipped if they have not changed).
To reach our goal of minimum required admin rights we thought it's an good idea to install into %LocalAppData% (perUser installation). Then we would only need admin rights on updates, if any of the 3rd parties have changed. But if our customer wants to install our application on a TerminalServer he sure wants to install it just one time for all users. So our files should be installed into C:\Program Files (x86) (perMachine installation).
To cover both scenarios, we made a Dual Purpose Package. Here we can decide at runtime, which type of installation is needed.
The problem: As already answered on stackoverflow, Burn (wix boostrapper engine) isn't able to deal with Dual Purpose Packages. (As I figured that out, I was literally freaking out)
My question: Is there a workaround? Is there any other possibility to reach my goal? Maybe another solution for installation on terminal servers. I'm stuck now. I don't wanna "install" our application using a self extracting archive or something like that instead of a msi package.
New approach 1: A different approach would be a update service. At the initial installation, we could install our application files to C:\Program Files (x86) and install then a update service which runs under LocalSystem. If there is an update available, our update sevice running as LocalSystem would have enough rights to do the update. Is there something like that already available? It doesn't have to be free, but i couldn't find anything :(
New approach 2: I could add a new "dummy" msi package to the bundle, which never gets installed. In this package I set InstallScope to perUser. This forces the bundle at compile time to be a perUser bundle. Here's what would happen (according to which option the user selects in our bootstrapper ui)
case 1 - user select perUser installation: Everything should be fine. Our bundle is fixed to be perUser and our dual purpose package (application msi) gets executed in perUser mode (parameter MSIINSTALLPERUSER="1"). A clean perUser installation, that's good!
case 2 - user select perMachine installation: Our bundle still gets installed just for the current user (fixed perUser bundle). So just the current user can see our bundle in "programs & features" and again just he can uninstall the bundle. That's not good. Regardless of that, our application msi gets installed perMachine (parameter "MSIINSTALLPERUSER=""). Not good, but also no disaster (or am I missing something?)
In my opinion, the second approach is a decent solution. If Burn will get support for dual purpose packages some day, I would just have to drop the then unnecessary dummy msi package and everything is fine.
Thank you guys very much in advance!

Related

Why would a WiX installation create two entries in HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\

I'm trying to uninstall an older version of our product which was installed using a WiX-built installer and after uninstalling it silently:
msiexec /x{GUID}
the program still appears in Control Panel. I've opened a separate item to
explore that mystery, but another curious issue has popped up. I noticed that after running the install for this program, two entries (GUIDs) are added to HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall. One with the product GUID and one that I have no idea where it comes from. I've searched through the .msi and it's not in there. Both are created each time I install, both are removed if I uninstall from the Control Panel and both are left in the registry if I uninstall from the command line. So have a look
Anyone have any ideas what's going on here?
Embedded Setup.exe: In essence it looks like you are installing an MSI that also installs an embedded non-MSI setup.exe via a custom action as part of its own installation sequence. Or, there is a setup.exe launcher that kicks off the MSI and the legacy setup in sequence. Result: two entries in Add / Remove Programs.
Uninstall: It is obvious, but to get rid of the second entry you must run its uninstall sequence - in addition to the uninstall of the MSI. Non-MSI setups are less reliable when it comes to uninstall than MSI packages. The implicitly available uninstall for all MSI packages with reliable silent running is one of the core benefits of MSI: MSI Core Benefits (among other topics).
Uninstall Commands: Try running the silent uninstall string, I guess that is what you have done?
Run commands elevated! With admin rights!
REM Uninstall MSI
msiexec.exe /x {PRODUCT-GUID} /L*v C:\MySetup.log /QN
REM Uninstall legacy setup.exe
"%SystemDrive%\ProgramData\Package Cache\{c5f0cb3e-1de3-4971-843a-abb981ed670c}\MDRSetup.exe" /uninstall /quiet
Silent Running: To run legacy setups silently you sometimes have to record a "response file" to record all settings in the GUI and pass to the uninstall process. I have some previous answers on this. You also need to run with admin rights:
Create MSI from extracted setup files
Regarding silent installation using Setup.exe generated using Installshield 2013 (.issuite) project file
How to run an installation in /silent mode with adjusted settings
Application Repackaging: What is the name of the software you are installing? MDRSetup.exe, is that Max Data Recovery 1.9? Probably not. Getting rid of legacy software can be challenging. You can always try to re-package it as an MSI if you have the tools to do so, or maybe you have a team in your company to do so (all large companies tend to). Not all legacy setups can be repackaged. There could be constructs that are impossible to capture, such as certain drivers, generated and unique keys per machine etc...
Links:
Create MSI from extracted setup files
How can I use powershell to run through an installer?
Wix - How to run/install application without UI
Capturing all changes during an application install on Windows

Windows per-machine install requires reference to original installer when second user runs application

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.

WIX Toolset - Install prerequisites based on user input

We are using the WIX Toolset among other things to automate a long installation process. A big part of this is installing lots of prerequisites that change based on what version of the product the customer wants to install.
e.g. there is a filter pack (.msi file) involved in the installation that only needs to be installed with a certain type of the product, so it is impossible to simple chain it into a bundle because we cannot know in advance which version the customer chooses.
Is there any way to solve this problem without having to create 4 different installers or installing all prerequisites regardless of version?
Thanks in advance.
The easiest and most maintainable (imo) method for implementing this is to use a burn bootstrapper and have a separate msi install for each version of the product the user could install.
The burn boostrapper would also contain all the prerequisite packages needed but only install the ones required by the specific version the user chooses to install.
You say you can't include the filter pack in the chain because you don't know until runtime whether or not the customer wants it but that's the whole point of the bootstrapper. Your bootstrapper should gather the information at runtime and set variables accordingly. Using the InstallCondition on the MsiPackage element you can determine whether or not you need to install the msi or not.
The bootstrapper process is to run Detect, do the UI, Plan, Execute. During Plan you will figure out which packages will be run and installed during the installation. The bootstrapper application has the authority to set any package to install or uninstall, overriding whatever the engine decides to do.
You could also include all the msi version stuff in one MSI and control it via feature groups which would allow you to use one MSI fo all the versions of your product but this can get bloated and complicated with multiple 'duplicated' components from different versions of your product so I think this would become a maintainability hell later on.
You can add a custom dialog which has checkboxes where the user can choose what to install.
These checkboxes set a variable to 0 or 1. You can use these variables in the installcondition.
I believe you can even conditionally show checkboxes(say 2 off the 5 are already installed, you would not want to give the user the option to install the already installed 2)

Having an issue with WIX upgrade

Having an issue with WIX installer upgrade. Previously we had 2 version of installers 1 for per-machine and another for per-user.
Currently we have developed a dual mode MSI.
The dual mode MSI upgrades the PerUser version (on PC 1) of previous installer when install for yourself option is selected but when install for all (on PC 2 ) is selected it install a new product
Is it some wrong that we are doing or is have to set some properties. We are using WIX.
Please help
Per-user installs allow the installation of the same product multiple times for different users - and in different versions too. This makes upgrades and patches rather difficult to deal with, and I dislike this per-user concept altogether. I prefer to set the installer per-machine as standard. I don't feel that much is lost in functionality, but a lot is gained in managability. Though this is not an answer to your question, it is worth pointing out that per-user installs is a flawed concept - at best.
I don't know if it is an option to set your installer per-machine, but I found a way to migrate installs from per-user to per-machine automagically by using Installshield and its custom ISSetAllUsers custom action. The procedure is described here:
windows Installer - uninstalling previous version when the versions differ in installation policy (per-user, per-machine)
Wix does not feature such a custom action as far as I know, but you could write your own custom action using the Win32 API call ::MsiEnumRelatedProducts() as described by Rob Mensching here: how to change from per user to all user installation?
Here is a similar post for reference: How can a perUser installation program deal with a perMachine older version of the program?
Here is a blog describing (further) issues with per-user installs: Understanding “Per-User” or “Per-Machine” context for application Setup packages.
Let me add a couple of further comments:
You can have per-user settings without a per-user install. This is no problem, just have the application set up the userprofile on launch. I prefer to install all resource files and settings per-machine and have the application copy them to each user for first launch initialization. This ensures that user settings are not entangled with your MSI at all.
It is rare to maintain two separate versions of the same product at the same time - hence users are all likely to use the same version of the product. Per-user is just more headache in this perspective.
The upgrade and patching logic involved in per-user installer scenarios beats me - it just doesn't make any sense to me. If there is a per-machine install already, does a per-user install make sense to you? Does this install the application one more time?
If per-user installs are still important, perhaps you can try ClickOnce (if it still works). Quote from Wikipedia: "...ClickOnce-deployed applications are considered 'low impact', in that they are installed per-user, not per-machine. No administrator privileges are required to install one of these applications. Each ClickOnce application is isolated from the others. This means one ClickOnce application is not able to 'break' another.". Per-user installs make more sense if they are hooked up to auto-updating and web-deployment.
If you had two setups before, it might be that you have two upgrade code and need to deal with both for the upgrade to work in all cases?
It has been a long time since I dealt with per-user stuff, but in general you must author your Upgrade table to include both upgrade codes for your setups to detect all flavours of your previous install. The upgrade table allows you to detect any number of prior installs that should be scheduled for uninstall before your new product gets installed.
The FindRelatedProducts MSI action will search all packages on the target machine in order to find any where the Upgrade Code property matches the value specified in the upgrade table.
Make a verbose log file as has been suggested:
msiexec.exe /I "File.msi" /QN /L*V "C:\Temp\msilog.log"
/I = run installation sequence
/L*V "C:\Temp\msilog.log"= verbose logging
/QN = run completely silently
I believe this is occurring because in your installer the default mode is Per-User hence it is not detecting per-machine.
You could use MSIGetProductInfo to find the installed products if the assignmenttype is “1” then you could set the below properties to Product Code of Per-Machine product
WIX_UPGRADE_DETECTED
OLDERVERSIONBEINGUPGRADED
Use a custom action on button click or schedule it after FindRelatedProducts.
This tells the installer of an existing version and installation is handle like an upgrade.
Windows Installer does not upgrade between per user and per machine, or vice versa. If you want this to happen you need to get in front of the install somehow and find out what type is already installed. Trying to do that when the product has been installed for another user (i.e. not the current installing user) is tricky. MsiEnumRelatedProuctsEx can be called a couple of times looking for per machine and per user installs to see what's going on. However there may be issues with you, User A, trying to uninstall a product that was installed per user by User B. If you are the same user it's easier. MsiEnumRelatedProductsEx can be called a couple of times to see if the product is per user or machine (in a launcher maybe) and you can uninstall the product before installing the new upgrade, or at least tell the user to do the uninstall. Anyway, it can be a mess, and the advice to stick with per machine installs is worth taking.
I should also point out that allowing per user AND per machine installs on the same machine is a feature, not a bug.

How do I create a Setup And Deployment project that can run any number of times on a machine without requiring an uninstall?

How do I create a Setup And Deployment project that can run any number of times on a machine without requiring an uninstall?
I've created an installer to install a WCF service to an IIS directory. It does more than just xcopy, it asks the users questions to correctly setup web.config.
The problem is when it can only be installed once per server without requesting an uninstall.
"Another version of this product is already installed...."
Typically the service will have 10-15 separate instances per server (each instance pointing most likely to a separate database, or a different security context)
I can't figure out how to set up the installer to do this.
Ok, I've got this working, I figured I'd answer it.
I downloaded the Orca windows installer editing tool (Part of the Windows SDK)
In the InstallExecuteSequence table, changed the following values to 0
RegisterUser
RegisterProduct
PublishFeatures
PublishProduct
This should allow the installer to run over and over without uninstalling.
It sounds like your program has 2 parts rolled into 1 - an installer and 1 UI based update service. Could you separate the 2 and have the installer check for being already installed and if so, fire up the UI program to run config setup.
If you want to install multiple versions of the same application you must do 3 things:
Ensure each version installs to a different folder, so subsequent installs will not overwrite previous ones.
You do this by changing the DefaultLocation property of the Application Folder in the File System panel
of the deployment project. A good policy it to use the application version as part of the location; e.g.
[ProgramFilesFolder]\[Manufacturer]\[ProductName]\[ProductVersion].
Ensure the ProductCode property of your deployment project is different, so subsequent installs
will not uninstall the previous version. The easiest way to do that is to...
Change the Version property of your deployment project. Visual Studio will ask if you want to change
the ProductCode property; you do.