VS Setup Project; How to restore a registry value on uninstall? - visual-studio

I have a setup project in Visual Studio. As part of the regular installation, it creates/updates some keys and values in the Windows Registry. How can I make the updates reversible?
you may say "they are reversible", but I don't think so. Here's how I think it works: USe the VS designer to specify which Registry Keys and Values you want. Those keys and values are written during install, and deleted during uninstall. Simple. What's not reversible?
The problem comes in when there's an existing value in one of the keys that is written during install. Suppose it has a value of 1. Then with the new install it gets a value of 100. After uninstall, it has no value at all - the value is gone.
I tried to work around this with "custom actions".
During install, if the user confirms, msiexec writes the values into the the registry. Whatever was in the registry key before, is gone. (Let's call this "Update A")
To preserve that value, on install, there's a custom action that reads and preserves the "before" setting. It runs before "Update A". So far, so good.
On uninstall, the normal course of action, is to remove the regular registry keys and values that were added during install. This works just fine. Call this "Update B".
To restore the original registry values, I have another "custom action". This one runs on uninstall. It successfully restores the original values into the Registry. The registry looks just as it was before the original install. I verified that this works using ProcMon (A tool that lets me monitor registry updates, among other things). Call this "Update C".
There's only one problem. On uninstall, Update B is happening after Update C. This means, after the custom action restores the original registry setting, msi wipes out the restored Value, as it does with all the other registry updates.
The result is the registry has empty Values instead of the restored ones.
Any help? How can I re-order the updates? Do I need Orca for this? I really don't want to install and learn another tool to make this happen. I also want it to be automatic. Definitely don't want to have to visually click through an MSI editor to make this happen.
Can I do this with a Javascript post-build event that uses the WindowsInstaller.Installer class? Aaron Stebner published a script that adds a "Launch application after install?" dialog to an MSI produced by Visual Studio. Windows Installer supports a "launch app" capability but it is not exposed in the designers for VS2008/2005. A quick biolerplate script, run as a post-build step in VS, added in the Launch dialog.
Is something similar possible with the ordering of custom actions?

Some answers for me:
Yes, it's possible to do this with a postbuild step implemented in Javascript.
yes, I'd use the WindowsInstaller.Installer class.
yes, orca was necessary to figure it all out
Orca clearly shows the custom action that is intended to restore registry values runs before the built-in action that removes registry values.
So I have to write a script to change the 1698 to 2620, and the registry values should get restored properly.
Edit: not so fast.
The idea is right, but it's not as simple as changing the sequence number. The problem is, the "preserved" registry value is in the registry tree that gets deleted by the uninstaller. Therefore, neither order works. If A is the restore, and B is the delete, A-B will restore the registry only to have the restored value later deleted. B-A will delete the value first, and then A will have no value to restore. The reason is that A (the restore part) stores the to-be-restored value in the tree that is to be deleted.
So the correct operation has to be something like A-B-A, where A takes the stored value-to-be-restored, and puts it in a place that won't get deleted by B. Then B deletes the app-specific keys and values in the registry. The A restores the setting that was socked away by A`.
To make all this happen I had to do some surgery on the MSI file, because the vanilla MSI designer in Visual Studio doesn't allow for setting specific sequence numbers. You need to use Orca, which is a GUI tool, or, in my case I used the COM interface to the WindowsInstaller to automate the changes via javascript.

Related

Registry entry that was removed on install not being replaced on uninstall

I have a Wix script with a RemoveRegistryValue element. It correctly removes the registry value when I install the product (provided I run with elevated privilege, which I am now). However, when I uninstall the product the registry value is not replaced.
If I wanted the value removed and never to be seen again I could have just gone into regedit and removed it. The whole idea of putting the removal in a Windows Installer package is so that I could uninstall the package and put everything back as it was should I need to. However this is not happening.
<RemoveRegistryValue Id='ShowLnk' Root ='HKLM'
Key='SOFTWARE\Classes\Lnkfile' Name ='NeverShowExt' />
On installation the value is removed (causing shortcuts to display their .lnk extension if you must know what it does). On uninstallation the registry value is not replaced (causing shortcuts to display their .lnk extensions forever, which is likely a good thing, but not relevant to this discussion).
How do I get the registry value back into the registry on uninstalling my product?
I've followed on now with another question here...Getting a custom action to run on install and uninstall
On uninstall, Windows Installer only "undoes" things that it actually created on the local machine during installation.
"Side effects" like removal of registry keys/values and files will not be undone during uninstall (though when a rollback happens, these will be undone as expected).
To support your scenario you have to do backup and restore of the registry value yourself:
On install:
Use RegistrySearch to get the existing value of 'NeverShowExt'. You may need to set Win64="yes", I'm not sure about that.
Store a backup of the value in your apps registry key (HKLM\Software\[Manufacturer]\YourProductKey).
On uninstall:
Use RegistrySearch to get the backup value from your apps registry key.
Create a deferred custom action that writes the registry value back to its original location. There is no declarative "WiX way" to write something to the registry upon uninstall.

MSI installer creates unattended shell open key

I created an MSI installer project in VS2015, set up everything, then added a file extension associtation with the "File Types Editor", assigned my extension to my application, as an Open command.
The COMMAND was the application from the "application folder", the EXTENSION was set, then the &OPEN was set as NAME=&Open, Arguments="%1" VERB=open. Nothing else.
I generated the .msi file, then started. At the end of the installation, I found out that in the registry Computer\HKEY_CLASSES_ROOT\\shell\open\command key there were two item, one is (Default) REG_SZ with value "myexe" "%1" as I expected
Unfortunately there was another item: "command", "REG_MULTI_SZ" and the Data was something weird, for example "LZ*a!t4(v=++Tt$)tOk_>[1jfrS!,nB`L6ciHLW!, "%1"" which I don't know what it is. When I delete the .msi file, and double click on a file with my registered extension, a popup dialog appears as "network resource cannot be found" and Windows wants my .msi installer back (browse dialog comes in)! I don't know how to prevent this unwanted situation. :( Any help would be highly appreciate!
Windows Installer uses so-called Darwin Descriptors to implement resiliency, wherein a corrupted installation can be repaired automatically. Your attempt to delete the .msi rather than to uninstall it acts like a corrupted installation, so the system attempts to fix it. However, since the .msi itself has been removed, it has to ask for help.
The short answer here is to suggest that you not worry about the exact values in the registry key. Since you're using an Extension table instead of a Registry table entry, the registry is an implementation detail; you should prefer to ignore such detail. Instead, if after a successful installation your program launches as expected upon double clicking the associated file, and it stops doing so after properly uninstalling your application, all is well.

Windows Installer doesn't finish installing until after application shortcut is clicked?

I have an MSI installer that was built from a VS2010 setup project. Part of the installation includes adding or modifying registry keys. (The keys are modified if the install is an upgrade, rather than a first time install.)
The installer works fine when it's a first time install, but when it's an upgrade it appears that the installation remains incomplete until an application shortcut is clicked. What I mean by this is: the installation completes successfully, however those registry keys will not exist until an application shortcut (i.e. in the Start menu) created by the installation process is clicked. At that point, the installer starts up with a message along the lines of Please wait while applicationXXX is configured.... This happens only once, after which the keys are written and all is well with the universe.
But why does this happen? And more importantly, how can I "force" the installer to complete the installation and write those registry keys without having to click an application shortcut? I should also mention that running the application's executable directly doesn't trigger this final installation process; it only seems to work if a shortcut is clicked.
Any help/insight would be appreciated.
Just in case someone else has this issue, it turned out that the true culprit was a Visual Studio bug: http://support.microsoft.com/kb/2418919
The installation is repaired automatically when using a shortcut because that shortcut is advertised. This is the normal Windows Installer behavior for broken installations.
To determine why your registry entries are not installed during an upgrade, try creating a verbose install log.
Most likely the key paths of your registry entry components are seen as already installed. This may happen if the key paths are files instead of the actual registry entries. You can check the key paths in Component table (edit the MSI with Orca).

How to find out defaults when executing MSI with /qn (silent mode)?

When I run an MSI (without parameters) I usually have to click my way through dialog boxes and choose if I want to install to current user/all users, the target directory, etc etc.
What happens when I run the MSI with /qn (silent mode). How do I find what answers where automatically chosen for all those dialog boxes?
An MSI is a basically a database. You can use Orca to open it and view/change settings.
Information on Orca can be found
here.
A quick walkthrough on how
to use Orca can be found here.
Somewhat pertaining to your
question, you can edit which users
the installer will install in silent
mode. Information is here.
I hope this has at least geared you in the right direction.
Edit:
For instance, download the installer for WiX 3.0 and open it in Orca.
Go to the Property table and you will see a list of public (uppercase) and private properties.
Notice that the WIXUI_INSTALLDIR property is set to APPLICATIONFOLDER.
Go to the Directory table, you'll see that APPLICATIONFOLDER is set to have a default of "vqee3ld3|Windows Installer XML v3" or something similar.
To find which dialog sets this property, go to the ControlEvent table. Here, you'll see the InstallDirDlg fires the event SetTargetPath when the user clicks the Next control. The Argument this event sets is WIXUI_INSTALLDIR, which in turn sets APPLICATIONFOLDER
You could try editing these properties and running the installer to see how the properties are changed. If you have default properties you'd like to set you can run. For instance, close Orca to release the lock on the msi file and run:
msiexec /i Wix3.msi APPLICATIONFOLDER="C:\Program Files\WiX" /qn
More on MSI table structures in this powerpoint
It is correct that you can set PUBLIC properties via the command line. These properties are always uppercase, and generally always listed in the Property table, though this isn't guaranteed to be the case. By reviewing the Property table you should be able to decode what each public property does. If not, there is usually documentation accompanying the MSI in form of a PDF or readme.txt that can help.
With the right tool you can also view the details of each MSI dialog and check the events that have been defined to set them. This requires a tool such as Installshield or Wise.
Another possible option for silent installation is a built-in MSI feature that I have just become aware of: the AdminProperties property. See information here: http://msdn.microsoft.com/en-us/library/aa367542(v=vs.85).aspx

Install Shield 2009 - Shortcuts creation

Is it possible to create shortcuts in Install Shield 2009 based on user input?
In essnes, a shortcut will be created (on the desktop) only if the user (who runs the installation) wants to do so
We have a screen that prompts the user to create desktop and quicklaunch shortcuts.
The shortcuts are then each in individual components with a condition set to only install if the checkbox was selected.
You also should store this response in the registry somewhere, and read it back during a reconfigure, upgrade, repair, etc. Otherwise if the checkboxes were on by default and that screen does not display to the user, the condition will evaluate to true (because the default property is true) and although the shortcut was not initially installed, it will be created during the repair if the components condition is reevaluated.
I do something similar to Sacha, but I'm lazier. ;-)
I create a component for each desktop shortcut (I hate software that assumes it's allowed to dump shortcuts on my desktop); no file in the component. Then I assign each of these components to its own feature. Then I can use standard feature selection dialogs (which is built in automatically and used when the user selects a Custom installation) to let the user select the desktop shortcut features.
I don't see a lot of software installers offering to install optional shortcuts in the feature selection dialog, but it strikes me as a natural place to do it. More technical users may see this as mixing metaphors.
FWIW, I originally did this in an InstallScript/MSI project, and I've just done the exact same thing in a straight MSI project, and the technique works fine in both.
It's been a while since I've used installshield, my company is currently using WISE as an installer; however, it should be possible to do what you are asking.
In general installer terms you need to do the following:
Make a screen for your installer that presents the option to create the shortcut, this screen should have the prompt text and a checkbox.
There should be a mechanism for storing the response of the checkbox in an Installshield property.
During the execution phase, use the reponse to trigger the creation of the shortcut.
I don't know about the capabilities of Installshield 2009 for whether this can be done without editing the script itself.
I hope this helps.

Resources