I'm struggling to find documentation on how the stateSaver/savedState Dictionary works for the Windows Installer, in the Install and UnInstall overrides, can someone help.
In my installers CustomAction I've been writing to registry entries, each time I do I add some of it's detail to the stateSaver. I had presumed this was taken into account when uninstalling but how?
I think the stateSaver Dictionary is written to file when you install, and on uninstall the content of that file, .InstallState is read and used to install the entries it finds.
How does the InstallState IDictionary work?
For registry entries in particular, do you add the Value in the InstallState as the full path the the registry entry? and at Uninstall will it install that registry key with any explicit code by the developer?
I'm creating a registry key with subkeys and values in my Custom Action, but it doesn't get uninstalled. I've added the key name as the Value in the InstallState but it doesn't get deleted. I've also tried deleting it programmatically in the UnInstall override but it fails, permissions I think.
My issue is some registry entries remain after uninstall, I don't know why and my lack of understanding of how the Dictionary works is not helping.
Here's an example of what the Install is doing
//add the root key of what I'm about to create to the InstallState.
RegistryKey expressionEvalKeyRoot = hKeyClassesRootCLSID.OpenSubKey("{" + guidString + "}");
stateSaver.Add("ExpressionEvaluator"+guidString, expressionEvalKeyRoot.ToString() );//will be deleted in the uninstall
RegistryKey expressionEvaluatorVersionKey = expressionEvaluatorKey.CreateSubKey(packageVersion);
stateSaver.Add("MyKey", expressionEvaluatorKey.OpenSubKey(packageVersion).ToString());
I would have thought that the base.Uninstall(savedState) would have uninstalled the key, both the root and the actual subkey, but it doesn't.
I also tried using DeleteSubKeyTree to delete the key from the root
RegistryKey hKeyClassesRootCLSID = Registry.ClassesRoot.OpenSubKey("CLSID") as RegistryKey;
hKeyClassesRootCLSID.DeleteSubKeyTree(savedState["MyKey"].ToString());
but I get an exception, permissions. I shouldn't need to do this anyway.
http://learnerps-dotnet.blogspot.com/ | | learnerplates Wednesday, August 26, 2009 11:09 AM | The only things that get deleted automatically are things that are "in" the MSI file, so files and registry entries that you create using the IDE are in the MSI file and get uninstalled. The MSI file is the repository of what is installed and uninstalled automatically. Nothing is monitoring what's going on and saying "oh, a custom action created a registry item so I'll remember to uninstall it later".
So I guess my question is: Why are you writing code to create registry entries instead of using the Registry view in the IDE? Or using the Register property of files you're installing that need COM registration? Phil Wilson- Marked As Answer bylearnerplates Tuesday, September 08, 2009 8:43 AM
-
| | PhilWilson Thursday, September 03, 2009 6:44 PM | Hi learnerplates,
Install state is a dictionary which is used to save information needed to perform a commit, rollback, or uninstall operation. In other words, we can save some information in a step of the setup and get that information again in another step. For example, we can add some information to the stateSaver parameter in the Install method. Then we can get that information from the savedState parameter in the Uninstall method.
In your code snippet, the information passed from install to uninstall is named "MyKey". This value is passed correctly, but you met some issues about permission. I have created a Setup Project to test, I cannot even add a registry in the Install method. The issue is also the permission.
Based on my understanding, it is better to add registry keys and values in the Registry editor. In this case, the registry keys would be removed when the program is uninstalled. The links below show some information about registry in deployment: # Deployment and the Registry: http://msdn.microsoft.com/en-us/library/3yxw87wf(VS.71).aspx.
# Registry Settings Management in Deployment: http://msdn.microsoft.com/en-us/library/w4dsy50b(VS.71).aspx.
Let me know if this does not help. Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. - Marked As Answer byAland LiMSFT, ModeratorThursday, September 03, 2009 8:36 AM
- Unmarked As Answer byAland LiMSFT, ModeratorThursday, September 03, 2009 9:03 AM
-
| | Aland Li Wednesday, September 02, 2009 11:03 AM | Hi Aland Li,
I know how to add and get from the IDictionary, but I'm not sure where it gets it's data from, I think it's the InstalledState file, the Hashtable seems to get populate by reading this file at uninstall time.
I found that I had to go through the SavedState in the Uninstall and read each value I was interested in and explicitly delete the registry entry myself.
Just to note on the registry entry deletion, you'll need to call OpenKey with the second param set to true in order to delete the entries,
e.g.
if(Registry.ClassesRoot.OpenSubKey(keyStringWithoutHKEY_CLASSES_ROOT, true) != null)
Registry.ClassesRoot.DeleteSubKeyTree(keyStringWithoutHKEY_CLASSES_ROOT);
I still don't know if this can be done some other way without calling the DeleteSubKeyTree, and letting the SavedState take care of it.
I know all about the registry designer but it was of no use to me in this case as the entry beeing added has a key that is determined at install time, I was unable to add this variable as a key in the designer.
Thanks for the help.
http://learnerps-dotnet.blogspot.com/ | | learnerplates Thursday, September 03, 2009 9:02 AM | Hi learnerplates,
As far as I know, there is no other methods except deleting registry keys directly. You need to try other deplyment tools such as WIX.
Regards, Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.- Marked As Answer bylearnerplates Tuesday, September 08, 2009 8:42 AM
- Unmarked As Answer bylearnerplates Tuesday, September 08, 2009 8:43 AM
-
| | Aland Li Thursday, September 03, 2009 9:09 AM | The only things that get deleted automatically are things that are "in" the MSI file, so files and registry entries that you create using the IDE are in the MSI file and get uninstalled. The MSI file is the repository of what is installed and uninstalled automatically. Nothing is monitoring what's going on and saying "oh, a custom action created a registry item so I'll remember to uninstall it later".
So I guess my question is: Why are you writing code to create registry entries instead of using the Registry view in the IDE? Or using the Register property of files you're installing that need COM registration? Phil Wilson- Marked As Answer bylearnerplates Tuesday, September 08, 2009 8:43 AM
-
| | PhilWilson Thursday, September 03, 2009 6:44 PM | Phil,
So nothing in the SavedState is automatically uninstalled, that's the type of information I'm seeking.
The SavedState is only for stored variables for later use in the UnInstall, because there is no instance to store the member variables at UnInstall.
There are a couple of cases in my install where the values are not known at design time e.g. a Registry Key I'm adding for a component in Visual Studio Extensibility requires the registry be the version number of the assembly, the version number is generated at build time, so what I do in the custom action is read this version number from somewhere and then write it to the registry at install time.
http://learnerps-dotnet.blogspot.com/ | | learnerplates Tuesday, September 08, 2009 8:42 AM |
|