Windows registry keys for applications for all users in machine - winapi

If I install an application on windows XP and that application writes some keys to HKCU registry , then will those keys be copied to HKCU for other users?
I tried installing one application and verified some keys getting created in HKCU.
Now I logged in into another user and I can find same keys in HKCU for that user.
Both the users were in same Administrator group.
I repeated the same steps in VMWare image of windows xp but I was not able to find the registry keys in other users in vmware image.
I want to know that is it windows feature to copy all registry keys in HKCU of all users?

No, and that's a very good thing. There are corporate machines in big companies that are usable by 100.000 other users (no joke). HKCU is roaming there. If an application would pull in all those 100.000 profiles from across the world, literally, administrators would be more than a little angry.
Note that HKCU usually is a link to HKEY_USERS\S-1-5-21-{UserID}

There are one nice feature of Windows which can be used to implement the scenario which are very close to what you need. The name of the feature is "Active Setup". The feature use many administrators of corporate network to make some customization of the installed software which will be done with respect of changes in the user profile or HKCU.
After introducing of Internet Explorer 4 (I hope it was IE4) Microsoft find out that sometime one need be able to run small setups which can modify HKCU setting or modify some files from the user profile. So Microsoft made some components of IE4 which do this. Later the components (the Active Setup) was the part of the Windows operation system.
Since the time one can use following registry keys to do this
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\[Guid]
and
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Active Setup\Installed Components\[Guid]
The main setup of a software run in administrative context and create HKLM key SOFTWARE\Microsoft\Active Setup\Installed Components\[Guid] with some values. The most important are the REG_EXPAND_SZ value with the name StubPath and the Version value. The StubPath define the path to the mini-setup which should be run if the user login and he don't has SOFTWARE\Microsoft\Active Setup\Installed Components\[Guid] in his HKCU part. After the run of the mini-setup it make the copy of SOFTWARE\Microsoft\Active Setup\Installed Components\[Guid] values from HKLM to HKCU, so the setup will not be started at the next login. So the HKLM values define the mini-setup and HKCU values are used for verification whether the mini-setup must be run/re-run. If one increase the value of the Version value in HKLM part, the mini-setup will be re-run once and the HKCU value of Version will be updated.
So the main software setup can not only create some HKCU settings, but also for example export it in the reg-file and it can use regedit.exe /s TheRegFile.reg as the value of StubPath.
If can read here short description of the Active Setup.

No you can't do this. What's more it would be a giant security hole if you could. Profiles are private to each user.

No. There is no such feature. HKCU is stored in a file in the user's profile. Applications that keep data per user in the registry create the data on the first run for that user.

Related

Write HKLM when installed as Administrator, but HKCU otherwise, in Inno Setup

I've created my Inno Setup installer and it is working great. I just have one issue I'd like to solve. Not all of my users have Administrator rights, so my app has been set up to allow non admins to install. The problem is, I have set up a file association for my application and consequently need to set the correct registry keys for this.
As my users aren't all Administrators, I can't just use HKEY_LOCAL_MACHINE (HKLM). At the moment, I'm defaulting to HKEY_CURRENT_USER (HKCU).
Is there an elegant way to conditionally set HKLM if the user is an Administrator (selected the "install for all users" option) and HKCU if the users selects install to their own profile?
Seems this will do the trick:
HKA (equals HKLM in administrative install mode, HKCU otherwise)
Testing it now.

How can I have my installer write to the HKCU registry tree?

My installer requires admin privileges. During installation some values are written to the HKCU tree of the registry of the currently logged on user. However, when this user account is a so called standard account, the user has to specify credentials for an administrator account when the installer starts. The values are then written to the HKCU tree pertaining to this admin account instead of the HKCU of the currently logged on user.
The same problem arises when the installer wants to write some data to the local AppData and wants to create a shortcut on the desktop.
How do I circumvent this?
This happens because you are using a per-machine installation which writes data in a per-user location (HKEY_CURRENT_USER).
The correct approach is to use either a per-user installation with only per-user locations or a per-machine installation with only per-machine locations (HKEY_LOCAL_MACHINE instead of HKEY_CURRENT_USER).
If you are asking for admin rights it normally means you are doing a system-wide/machine install for all users. When creating this type of installer it is not a good idea to write to HKCU or %USERPROFILE%, not just because you can end up performing actions for "the wrong user" but you also end up initializing the install for just that one user and not all users.
What I recommend is that you write this common data to HKLM\Software\YourCompany\YourApp\CommonData and/or <CSIDL_COMMON_APPDATA|CSIDL_PROGRAM_FILES>\YourCompany\YourApp\CommonData and then import this data in your application the first time a user run's it.
You might also want to consider creating a per-user installer (like Chrome) but this means you can only write to HKCU and %USERPROFILE%!

HKLM registry doubt

My application updates some registry fields related to licensing under HKLM. This is for accessing the information for all users in the system. This makes us to make our application run as administrator. Is there any other location in registry where I can keep information which can be accessed by all users?
Registry HKLM and folder %ALLUSERSPROFILE% are accessible to all users, but meant for writing to at install time (as admin).
Registry HKCU and folder %APPDATA% are accessible to current user and meant for writing to at any time.
Why are you modifying licensing info (shared by all users) during run and not just during install?
You could place as an (e.g.) XML document in the file system under a shared folder instead of the Registry.
E.g. System.Environment.SpecialFolder.CommonDocuments or CommonApplicationData.
No there is not. If you have to make a modification that will affect/be visible to all users, you have to deal with UAC or elevate your application on startup. This is part of the design of UAC. If, however, you were to write to a file you could grant all users access to that file without UAC interference.
If, however, you are only reading the registry, you can do this without elevating your security rights. Therefore, if you write once to the registry and then just read it later, you can do so when only elevating your privileges once.
Here is an article on playing nice with UAC:
http://msdn.microsoft.com/en-us/magazine/cc163486.aspx
I'd make your installer precreate the registry entries (it runs as admin typically), and open up their permissions using GetSecurityInfo and SetSecurityInfo. Then your app can write to them without any special perms.

Windows 7 elevated registry access

I'm working on an installer for our application. The installer makes some changes to the HKEY_CURRENT_USER\Software\Company\AppName registry key, which the application then looks for the first time it runs. The application then does different things based on the registry keys it finds.
This works great, until you try to install the application as a user account (i.e. non-administrator) on windows 7 (and maybe Vista, I haven't tested that yet).
When the user tries to install the application, Windows elevates to the administrator account's credentials. This means that any changes to HKCU in the registry are made to the administrator's registry, not the launching user's registry. Thus, the keys are not visible to the application when it launches for the first time under the user's account.
We can't be the only people whose installer needs to communicate with the app it installs. Is there no way to reliably use the registry to do this?
We can't rely on the user launching the app after he installs it, so passing the information as a command-line parameter isn't a viable solution. The only way I can see to do it is to have the installer invoke a utility as the original user, which gets or sets the registry key itself; this seems to be a bit of a silly hoop to have to jump through.
Edit: The application needs to delete the keys after it's used them, so I can't just put them in HKEY_LOCAL_MACHINE.
There are 2 recommended approaches for what you want:
Use a per-user installation which
doesn't require Administrator
privileges. You will be able to use
HKEY_CURRENT_USER, but your product
is not installed for all users.
Use a per-machine installation which requires Administrator privileges. In this case you need to redesign your application so it reads its settings from a configuration file. HKEY_CURRENT_USER should be used only when saving user-specific settings, not for global application settings.
Basically, if your application is per-machine, it should use HKEY_LOCAL_MACHINE or a configuration file. If it's per-user, you can use HKEY_CURRENT_USER. Any other combination has limitations and will not work the way you need.
If you need your application's information to be available to all users, use the HKEY_LOCAL_MACHINE hive.
EDIT - 2 alternatives:
Change the security of your registry
keys to allow users to edit/delete
them,
Use the ProgramData directory (instead of the registry) to store
the data.

Access to HKLM registry branch on Win 7 from within application

Is it possible to write to the HKLM registry branch in Win 7 from an application?
My existing code is not able to write to the HKLM registry branch on Win 7 machines, while it is able to do this on XP machines.
How do you allow an application read/write access to HKLM on Win 7, or should all applications now just use HKCU instead? What if I need to store settings on a machine basis rather than a user basis?
You need to decide whether you are writing an administrative app, that deliberately changes settings for all users (by writing to HKLM) or an ordinary app, that does not. If you really are writing an administrative app then put a manifest on it that has a requestedExecutionLevel of requireAdministrator. The user will get a UAC prompt every time they run the app, but your writes to HKLM will succeed. Alternatively, change the app to write to HKCU or some other per-user store.
(No idea how to add a manifest? Tell me what language/IDE you're using and I'll try to help.)
Relying on virtualization is a bad idea. It was implemented to let unmanifested applications at least sorta kinda work. It will go away some day and is not that great while it's here.
Win 7 uses Registry Virtualization
Read the article and look into (HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software).

Resources