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

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.

Related

Modifying the registry with msi installer

I am using Visual Studio's MSI plugin to create an install. My intentions is to make it run on startup using the registry HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
for example this is Skype's key in the registry
"C:\Program Files (x86)\Skype\Phone\Skype.exe" /minimized /regrun
The problem I have is I created a string key in that location but I just need to make sure it's pointing to my program I'm installing which would be in their "Application Folder" but I am not sure where that would be(Program Files or Program Files (x86) or user defined location).
Is there a variable I can put in the value that would point to my program despite where it goes?
The kind of thing you want in the Registry view in the IDE of the setup project is to have the Value of the string in the registry be [TARGETDIR]My.exe
TARGETDIR is the property name for the Application Folder (see the properties window) and specifying it in square brackets causes it to be resolved to the actual value at install time. Note that you don't need a slash because [TARGETDIR] has a trailing one.
This should be a good start, despite being old:
https://www.red-gate.com/simple-talk/dotnet/visual-studio/getting-started-with-setup-projects/?_ga=2.217704863.888096756.1503861862-798639290.1503861862
https://www.red-gate.com/simple-talk/dotnet/visual-studio/visual-studio-setup---projects-and-custom-actions/?_ga=2.112181773.888096756.1503861862-798639290.1503861862
https://www.red-gate.com/simple-talk/dotnet/visual-studio/updates-to-setup-projects/?_ga=2.112181773.888096756.1503861862-798639290.1503861862
and the docs start here:
https://msdn.microsoft.com/en-us/library/wx3b589t(v=vs.100).aspx
and the standard properties start here, such as TARGETFIR:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370905(v=vs.85).aspx

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).

Rename a directory in installer

I am working on a Windows application which needs to be able to update itself. When a button is pressed it starts the installer and then the parent application exits. At some point during the installer, the installer attempts to rename the directory that the parent application was running from and fails with "Access Denied" If you run the installer from the desktop it works.
I am using CreateProcess to start the installer, is there some way of using this or another API to create the installer completely independantly from the parent application so that it doesn't retain some attachment to the directory.
I'm not convinced that launching the installer separately will solve your issue. It sounds more like a permissions problem that you might be able to solve using ACL manipulation. If the app doesn't already have permissions to mess with that folder, you might be able to write a custom action to remedy the problem by adding the necessary permissions to your process.
Another way of doing this is to make sure that the directory deletion is happening within a custom action that you control (as in, you own/maintain the code that performs the deletion, rather than rely on MsiExec to do it for you). Then, set that custom action to run in the System context so that it will have the same permissions as a service. That should provide your installer with sufficient rights to remove the folder.
You should use the normal update system within the windows installer.
your access denied message appears because file/directory is in use.
renaming directories isn't also not a good idea.
what happened if the user clicks "repair" or "uninstall" ?
you can start the msi with shellexec. after that terminate you app immediately.
you should check that in the msi that your app is NOT running anymore.
do the update. if a file is in use the installer automatically wants to reboot to replace the stuff.
CreateProcess should work if you are passing it the right parameters. Don't reference the parent process in any way and set most things to NULL. If that doesn't work, then you can try WinExec().

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

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.

Resources