How to remove registry keys on uninstall msi using WIX - c#

I need to remove registry keys when user uninstall application.
These registry keys are in HKEY_CURRENT_USER\SOFTWARE.
I am using WIX tool.
Please note that keys are not getting registered on install but after login based on action performed by user.
Thanks in advance

Windows Installer can only access the registry hive of the user it's running as. It's technically possible to write a custom action to enumerate the user profile list and load each ntuser.dat but this ultimately causes all sorts of problem. The short answer is it isn't practical. Besides, Microsoft standards state to leave user data behind on uninstall.
If you really want to do it, the best way I know is to use a custom action to write to the registry during uninstall (something MSI doesn't support). Have this registry value set up an ActiveSetup command to invoke reg.exe delete. Then when each user logs in next time the key will be deleted.

Related

WIX non admin Installation

I have an issue regarding wix setup generation, here is my scenario
I have created a setup and tried to install on completion of installation I have done code to create a key in HKCU(H key current user), upto here it is fine.
Now if I try to install with non admin rights then it asked for admin password, then I have entered, installation is completed, problem is the key which I tried to insert in HKCU (Current User) is inserted into the admin account not in the current account where I am installing.
FYI
I am using C# winforms and WIX to generate setup
Any help would be greatly appreciated..
Kind Regards,,
Raghu.M.
You can create an installer that can be executed by non-administrator: https://stackoverflow.com/a/14358274/129269
As mentioned you can no longer install things that require elevated privileges. But on the other hand, when trying to add values to the HKCU my guess is you don't want to install system wide resources.
Update your application to write the default HKCU registry data on first launch. It is much easier than having your setup do the job.
For a description on how you can manage HKCU values after they have been written - in case they need modification, deletion or changing during a reinstall of the application - you can check this thread: http://forum.installsite.net/index.php?showtopic=21552
Thanks for your reply,
This is the way, I approached to solve this.
I have created a component where it inserts key in Local Machine Which will be common for all, and thereby proceed further.
Kind Regards,
Raghu.M

How to allow non-admin user to write to registry key HKEY_LOCAL_MACHINE\SOFTWARE\SWname\Licenses

I have a software deployed using Windows Installer.
On Windows XP, When I use non-admin user to install the software package, it asks for administrator's right which is correct.
Then I click run as administrator and wait for the installation finish.
Then if I (non-admin user) want to write to registry key "HKEY_LOCAL_MACHINE\SOFTWARE\SWname\Licenses", the software throws an exception. The access is denied.
I use follows in the source code :
RegistryKey rk= Registry.LocalMachine.CreateSubKey("SOFTWARE\\"+swName+"\\Licenses", RegistryKeyPermissionCheck.ReadWriteSubTree);
But still cannot access to the registry key if I am an non-admin user.
How to allow non-admin user have write access to the registry key under my software ? Like adding a license ?
The first thing to point out is why do you have a custom action instead of using the Windows Installer Registry table? A per-machine installation is "managed" or "trusted" meaning that subsequent repairs/reinstallations will automatically elevate and have permission to update the registry.
You can use the LockPermissions table in Windows Installer to relax the permissions on that registry key. Assuming it's a safe and appropriate thing to do so.

App is unable to write to the registry, even though the user has administrative privileges

I am using Visual Studio 2010, and I'm writing a program that needs to set (and read) new registry values under HKLM\Software\myapp
The program is .NET 2.0-based and as for now it runs on Windows 7 64-bit. Here is my ocde:
RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software", true);
RegistryKey MyKey = softwareKey.CreateSubKey("MyApp");
RegistryKey = MyKey.CreateSubKey("MyKey");
selfPlacingWindowKey.SetValue("instaldateperson", datestr + usrname);
The problem I have when running Visual Studio 2010, is that it will run the app but logged on as me, I am a user and member of local admin group.. however I cannot create the key (despite I am part of local admin group, who have rights to do so). Neither do I know how to do it as a logon as (but its also not what I want since then I would put Adminuser and password inside the code, and I already am admin ?? so why ??)
If this isn't possible at all, are there options for creating registry keys?
Somehow add them to the project or so ??.. I am a bit confused here.
Just because you're running as Administrator (or using an account with administrative privileges) does not mean that those administrative privileges are always in effect. This is a security measure, preventing malware from exploiting users who foolishly use their computer all the time with administrative privileges.
To wield your administrative privileges, you need to elevate the process. There are two ways to do this:
Use a manifest that indicates your application requires administrative privileges, and thus demand elevation at startup.
This means your application will always run elevated and should only be used when your application needs this. The Windows Registry Editor (RegEdit), for example, does this, because there's little you can do there without administrative privileges.
Find information about how to accomplish this here on MSDN, or in my answer here. Basically, you just want to add the following line to your manifest:
<requestedExecutionLevel level="requireAdministrator" />
If you only need administrative privileges for certain tasks (i.e., saving a particular setting to the registry) and the rest of your application does not require it, you should launch a new elevated process to do this. There is no way to temporarily elevate the current process, so you actually need to spin off a new process.
The advantage of this method is that your application does not have to run with administrative privileges all the time (which increases security), and that users who do not have administrative privileges will still be able to run your app to do everything else (i.e., everything but the one or two tasks that do require elevation).
You spin off a separate process that contains only the logic needed to write to the registry using the Process class and request elevation for this process using the runas verb. For more information, see this question. I have also written an answer that provides a complete description how to accomplish this from C#, including sample code.
Of course, as other answers have mentioned, it is more likely that the design of your application is incorrect. The whole logic of the Windows security model is that regular applications to not require administrative privileges. They don't need to write to the registry or do other things that could potentially compromise the machine. If you need to persist settings, might I suggest two other possible approaches:
Recognizing that Windows is indeed a multi-user operating system and writing your settings only for the current user. This makes good sense anyway because different users often have different settings and preferences. Instead of the HKEY_LOCAL_MACHINE branch of the registry (which requires administrative privileges to access), you would want to use HKEY_CURRENT_USER. Change your first line of code to:
RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey("Software", true);
Skipping all of the hassle and complication of writing to the registry altogether by using logic built into .NET to persist your application's settings. Start reading the answers here, or here, or on MSDN to learn how to do that. I'd say that this is by far your best option. Don't write complicated code yourself to do something that the framework you use already has built-in support for doing with ease.
The design of your application is probably wrong. Standard desktop apps are not supposed to write to HKEY_LOCAL_MACHINE. Because of UAC, you need to have administrator rights, and be running in an elevated process in order to be able to write to HKLM.
If your application does need to make changes to HKLM then consider doing so at installation time because the installer will be run elevated.
If a desktop application does need to write to HKLM then it should consider separating those parts of the application that need to run elevated into a separate process. Otherwise the users are going to be very fed up with having to go through a UAC dialog in order to run your application. Even if they aren't using the part of the application that writes to HKLM. And if you force the entire app to require elevation then standard users can never run it at all.
The reason you can't create the key under HKEY_LOCAL_MACHINE while running Visual Studio is because Visual Studio isn't running as an elevated process.
For end-users the manifest of the application needs to indicate that full Administrator privileges are required. Here is the documentation on embedding a manifest for UAC
If the registry key doesn't need to be global on the machine consider writing to HKEY_CURRENT_USER instead.
You should to give writable permission adding true value after your key in the method.
Registry.LocalMachine.CreateSubKey(#"YOURKEY", true);
Registry.LocalMachine.OpenSubKey(#"YOURKEY", true);
Also you need elevated permissions to do that, then you can create a .manifest file and setting the level in requireAdministrator like that:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
NOTE:
In your code:
RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software", true);
RegistryKey MyKey = softwareKey.CreateSubKey("MyApp");
RegistryKey = MyKey.CreateSubKey("MyKey");
selfPlacingWindowKey.SetValue("instaldateperson", datestr + usrname);
Check if the object label si correct, you are using the labels softwareKey and MyKey to create an object but to set the value you are using another label selfPlacingWindowKey.
Resuming. Create a .manifest file in your project. Give it the same name as the executable. "name_of_executable.exe.manifest" Finally change or create the tag for:
<requestedExecutionLevel level = "requireAdministrator" uiAccess = "false" />
The previous answers mentioned that you need to specify in the manifest that you require administrator permissions to use HKLM
You can create a manifest by;
Right click on your project,
Going to Add New
Click On General
Click on Application Manifest File
Click Add
Open your manifest file and find and un-comment the requireAdministrator line
The more nuanced thing that may be tripping you up is having Prefer 32bit ticked in your project settings.
This will mean that the Registry can't get the access mask it requires and it will fail silently without an inner exception because the error handler needs the same access mask so it can't be exploited.
You should avoid storing things in this part of the registry unless you absolutely need to persist settings across users, The registry also shouldn't be used to store passwords or other sensitive information as you can NOT reliably control access even with ACLs.

Storing Licensing Information in HKEY_CURRENT_USER Branch of the Registry in c#

I'm trying to save user registration data to the registry in c#. But without administrative rights i cannot access HKEY_LOCAL_MACHINE. I don't have admin rights, so i decide to store it in HKEY_CURRENT_USER branch.
Is this approach good, i.e. if a user registers the product and he switches the account in windows, the application will be unregistered. Does commercial softwares use HKEY_CURRENT_USER branch to store license key of the user. Since the license is for a single user is there a problem if i only allow a single user(a windows user) to use the key preventing other users from its use.
Why do not save some key file with user specific license agreement in
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)?
The user that runs your program has access to that location granted by system itself.
You can elevate the process when the user is activating the product so that the write access to HKLM is allowed.
Depending on your license model I would recommend registering the product per machine as in this way different users can all use the license.
But if you want to allow only the original user to use the license then HKCU is fine.
I tend to stay away from the registry unless I can help it. This way would be very easy to pirate if you are selling your product, although there may be no possible pirate-proof ways I wouldn't recommend using the registry.
An approach I have used before is to save the license key in your app's app.config. Then it is compiled with the app so you don't have anything computer specific to depend on. When your app is activated the key is saved in the config file and on each opening of the app it just does a bool check to see if it is valid.
This way also makes it harder for computer savvy users to pirate your software.
Hope this helps.

download click once application from browser

i was working on win application made its setup, and put it on site. when some user comes to site for first time it pormpts user to download my application. and while running setup i created a key in registry, that was checked in my script by site, that if key exists than user will not be prompted as he/she has installed app. when user uninstalls application, setup will delete regisrty key, wirtten on installation time.
Note: i added my site to trusted site and chaged its security to read my script.
Now scenario changes, user has asked to implement app in clickonce, so that they had to update app instead of uninstall and reinstall it. they still want clickonce app setup on site as mentioned above, but problem here is that when i run app first time it will write registry for that application but on uninstall it will not delete registry. as it is mentioned in following link set registry key through click once.
is there any way to accomplish this requiremnent. any help will b appreciated
check the update option is enable in the Publish settings ( if needed specify the minimum version for updating specify it also) .
when the application starts it will automatically checks for update. user dont need to uninstall every time
If you want to remove a registry key before the application uninstalls you will need to launch the uninstall process from a location within your code that you can control. To do this, you will need to have the user launch the uninstall process from within your application. When the user starts the uninstallation process, you will need to remove the registry key from within your application before continuing the uninstallation.
There is an excellent blog post (found here) by Jim Harte regarding automating the uninstall/reinstall process. His article is in regards to an issue with certificate renewal, but the uninstall process is the same.
If your user uninstalls the application through the Add/Remove Programs dialog, the key will not be removed. There is unfortunately no way that I am aware of to halt the uninstall process of a ClickOnce application so that you can remove a registry key. It's just an annoyance that you will have to live with, unless someone else around here has found a "creative" solution.

Categories

Resources