VS or WIX MSI installer - show serial number from first install - visual-studio

I'd like to show the serial number in the CustomerInfo form (which was captured from the first install and installed in the registry) within the second, third, etc installs when the upgrade is simply a minor version change (or patch). Is this something that can be done within VS deployment project and/or WIX via a custom action (I have a C++ method to fetch the SerialNumber from the registry), MSI config (thru editing a table(s) via say Orca), or otherwise
Regards
Travis

Personally I always do PerMachine installs and don't bother to show the customer information dialog. If an application wants to have licensing it's best to do it in the application on first run.
If you really want to do it in the MSI, you've got a lot of work ahead of you. MSI doesn't persist properties across transactions so you'll have to do it yourself. See:
The WiX toolset's "Remember Property" pattern
I have an open source project called IsWiX. It includes a Visual Studio project template that creates an installer project framework. Part of that framework shows how to insert a custom dialog and then authors a component to handle the remember property for the control on that dialog. You can find the source here.

I'll skip the WiX part that Chris covered.
To do this in a VS project you're supposed to use the Customer Information dialog, added from the list of extra canned dialogs, and use the SerialNumberTemplate stuff. That sets the ProductID property which is the way you're supposed to do serial numbers. So then you could create a registry item in the Visual Studio IDE that has the value [ProductID] to save it somewhere personal. The "official" way to get hold of it for an installed product is MsiGetProductInfo() or equivalent passing the ProductCode and asking for "ProductID" as documented here:
http://msdn.microsoft.com/en-us/library/aa370130(v=vs.85).aspx
To summarize, if the package uses the official PIDKEY /ProductID mechanism (like VS and maybe WiX) you don't need to save it yourself and you can get it via MsiGetProductInfo() or a scipt/managed code equivalent.
If you want to show that previous SerialNumber in a VS setup in the standard customer information form on an upgrade, I don't believe you can do that. There's no mechanism for getting into those forms. If you save the SerialNumber privately, you could try a registry search for your saved serialnumber and store it in the PIDKEY property to see if it shows up there, that might work because the PIDKEY property is the source for that value.

Related

VS setup project destroys self when installed files are deleted

This should be pretty simple, but I can't seem to get it. I have a setup project (VS2010) that packages a few dozen image files (along with my SQLite file) and copies them to the user's computer when the program is installed. As these are essentially "stock" images, it's ok if the user deletes them (there is functionality to do so from within the program.) However, after one or more of these images have been deleted, the next time the program starts it gives a "Windows installer" dialog box, and deletes all of the remaining data files!
What I think is happening is the program sees the missing files, assumes the installation has been corrupted, and tries to go into some kind of recovery/uninstall mode. I'd like to know how to indicate in the setup project that the files need to be installed, but may be removed by the user at any time.
I have tried several combinations of File properties, and nothing seems to do quite what I want, which is for my installer to put them where I say and never think about them again. Do I have to reinvent the wheel and do this through a custom action??
EDIT: Transitive and Vital had both been set to True. Setting them to False causes the program to re-add the deleted images back after it has been restarted! I'll probably go with a custom action if I don't get an answer.
When using a file association or advertised shortcut Windows Installer automatically checks if component key paths are missing. If a key path is not found, a repair is trigger to reinstall the component.
Most likely your installer repair process does something that removes the other files.
A solution is to not register your components with Windows Installer. This is done by using a null component GUID and it's not supported by Visual Studio setup projects (it is however supported by most of the other setup tools).
Another solution is to make sure that your image files are not key paths in their components. This is also not supported by Visual Studio.
If you want to use a setup authoring tool which offers more control, you can take a look at this list: http://en.wikipedia.org/wiki/List_of_installation_software

Duplicate entries in Add/RemovePrograms control panel when using MsiSetExternalUI

I created a setup for my product targeting Windows XP and later, to be installed using windows installer (WI). The resulting .msi file has a product code, let's say PC1 (actually a guid), and an upgrade code UC1 (also a guid). After some time, I created a new setup for a newer version of my product. The new .msi file has a new product code PC2 and the same upgrade code UC1 (also called a major upgrade). My company wants to install the .msi file with our own installer. For that, we basically use MsiInstallProduct to install the .msi file, while the entire UI is in our own install program (and we use MsiSetExternalUI to ask WI to send us notifications). The problem that I am having is the following:
if the two builds of the product are installed on the same machine using "msiexec /i myapp.msi" then there will only be one entry in the "Add/Remove Programs" of "Programs and Features" control panel applet. or in other words, during the installation of the new build, the old one is uninstalled.
if the two builds are installed on the same machine programatically using MsiInstallProduct, there will be two different entries in control panel.
Once again, only if I try to install it programatically (using either MsiOpenPackage+MsiDoAction or MsiInstallProduct), the upgrade does not happen and I end up with two entries in the control panel. I also found that if I do not set an external UI callback using MsiSetExternalUI, before calling MsiInstallProduct or MsiDoAction, then the upgrading part of a new installation also works as expected, no duplicate entries in the CP.
The callback that I use for MsiSetExternalUI is basically the same as the one in this MSDN article:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa368786(v=vs.85).aspx
What can I do (or what I need to handle in my callback) to avoid having duplicate/multiple entries in control panel?
Thanks and best regards,
Levente
Re our comments above, I did a google search for CLIENTUILEVEL and the first several hits indicate to me that CLIENTUILEVEL having a null value is normal and that REMOVE=ALL is working. The comments indicate to go a little furthor down the log and find out why the uninstall (Remove existing products) is failing. If you could email me a complete log file ( chrpai#iswix.com ) I could look through it for you.
RemoveExistingProduct standard action
Link to article describing how to interpret Windows Installer log files (see comments)
RemoveExistingProducts running but not uninstalling Options
I ran into the same behavior with my ManagedMsiExec sample project: http://blogs.msdn.com/b/delay/archive/2012/01/09/make-things-as-simple-as-possible-but-not-simpler-managedmsiexec-sample-app-shows-how-to-use-the-windows-installer-api-from-managed-code.aspx
Changing the logging behavior of my app didn't help in my case. But after (independently) noticing the same "CLIENTUILEVEL= REMOVE=ALL" strangeness in the logs, I found a workaround which was to explicitly call MsiSetProperty and set CLIENTUILEVEL to 0 before calling MsiDoAction.
This appears to me to be a bug with Windows Installer itself (incorrectly setting CLIENTUILEVEL during RemoveExistingProducts), but perhaps there's something else going on I don't understand. At any rate, I've had success with this change and maybe others can, too. :)

visual studio 2010 setup project - removing registry

I have 2 msi files that I run silently one after the other from win forms application (master installer for that matter). Both of them configured to write to registry to same location,
for example:
HKLM\Software\MyProduct\MSI1
HKLM\Software\MyProduct\MSI2
Now, I run uninstall in reverse order and when uninstall done, MSI1 removed from registry, but MSI2 is stuck there... Is there anything can be done about that without custom action or coding?
This happens because your registry entries use the same component as another product installed on the machine. For example, you copied the setup project of an existing product and used the copy to create an MSI for a different product.
To avoid it, you need to make sure that each MSI uses unique component names and GUIDs. It's not easy in Visual Studio setup projects. You can try editing the project file. If it doesn't work, it's better to start from scratch with a new setup project.
Ok, I found problem in VS2010 (Big Thanks to Cosmin Pirvu) and just will go on and put here the 2 solution options I see so far. But first, the problem:
As I mentioned I have 2 entries:
HKLM\Software\MyProduct\MSI1
HKLM\Software\MyProduct\MSI2
But in code, they look the same because MSI1 and MSI2 being "place holders":
HKLM\Software\MyProduct[ProductName]
So, the name is identical and properties identical this is why we get same component id for both!
Two things (as far as i see) you can do:
Instead of [ProductName] enter actual product name (hard coded)
(What I did is) In registry entry property, in condition field, enter meaningless string (make it really meaningless, so it wont meat reasonable condition, i used guid with leading __).
Thanks for all answers

How to use VS Installer class in a Custom Action

Dozens of Q&A entries (all but one in stackoverflow!) that I found got close to this question, but didn't teach me what I needed. I have what should be a nearly simple installation: a Windows service and an associated tray icon application. They install fine with the standard VS Setup project. After the files are installed, I need to present a dialog to the user to set some parameters in the service's exe.config file. In that dialog, the user should be able to abort the installation. I've tried two approaches to the Custom Action process and ran into a wall with each when it comes to making the installation roll back.
Approach 1: An exe for the Custom Action, run at Commit time.
This sort-of works. The application returns a non-zero exit code and the installation rollback occurs. What I don't like is that:
When the app exits (after the user selects to Cancel), the installation displays an error message saying that there was a problem with the installation and the user should contact the vendor. Since that's not the case, I'd prefer a more correct message ("Installation canceled by user") or no message at all.
Both of the project outputs (the service and the tray app) have to be listed under all four Custom Action sections or my dialog won't appear. Instead, an error appears about a missing InstallState file and the installation always fails. Intuitively, this seems wrong.
Approach 2: An Installer as the Custom Action, run at Install or Commit time.
This is cleaner to me (only the one item listed in the Custom Actions), but getting the process to roll back is worse than Approach 1. It seems that I have to throw an exception in the overridden method (Install/Commit), which then gives me several error dialogs before the rollback occurs, and then the rollback doesn't always uninstall the service.
What is the cleanest way to make this work without going to WiX or similar options?
The simple answer is don't use VS Installer Classes. They have a number of fundamental design flaws. I suggest you look at Windows Installer XML's ( WiX ) Deployment Tools Foundation ( DTF ) instead. DTF is a far superior hosting model / interop library for your managed code and outputs DLL's that are compatible ( from an MSI perspective ) with C/C++ custom actions. They can be consumed as Custom Actions by any MSI authoring tool, not just WiX installers.
Deployment Tools Foundation joins the WiX toolset.
Deployment Tools Foundation (DTF) Managed Custom Actions
I recommend this approach:
create a custom installation dialog which asks the user about your options
use the installer properties set by this dialog to modify your service configuration file (you can use a custom action or the XML support of another setup authoring tool)
This way the information is gathered before the install and the user can also abort the install without problems.
This approach is not supported by Visual Studio, but it can be done with free or commercial setup authoring tools.
If you want to stick with a custom action, you can try this:
make sure your custom action is deferred and doesn't run during commit (commit means that the installation was performed and there's no rollback)
use a Win32 DLL to show your custom dialog; this way you can return ERROR_INSTALL_USEREXIT (1602) so a friendlier user exit dialog is shown instead of the fatal error dialog

Visual Studio 2005 Setup project application folder default location on potentially non-existent volume

I have a Visual Studio 2005 solution that includes a setup project. The setup project specifies "d:\somefolder" as the Application Folder DefaultLocation property. When installing on a machine without any partitions mapped to "d:", the resulting installer craps out with the message
"The volume d:\ is currently unavailable. Please select another."
Trouble is, you don't actually get a chance to select a different install location (on an existing volume). What settings should I use to enable the user of the installer to change the install path, while keeping the default as d:\some_folder?
the Setup and Deployment projects from VS leave quite a bit to be desired. Every solution I am aware of will take a bit of reading and learning, as the GUI tools that make setup's for you are normally rather limiting in customization outside the realm of changing the actual look of it. I would recommend looking into the WiX (Windows Installer XML) toolset for making installations. The learning curve is one of the most user friendly ones that I have seen on the market, plus it is a free tool. As long as you have a fairly decent understanding of XML you have everything that you need in order to start making MSI's.
I suppose there should be setups available which let you change the destination.
Or you could use orca to add in a dialog box which specifies that.
Or you could pass it in as a commandline argument if the user is on a commandline interface.

Resources