Setting registry value for all users
What is the best way to set registry value for all users on a machine. Enumerating HKEY_USERS and changing ntuser.dat is one solution.
Any other sol开发者_开发百科ution that can be used in XP,VISTA as well as Windows 7?
Actually installer needs to write one key into registry. And that key need to be used by all users. Once its used key should be reset.
This cannot be done if we keep only one copy of key in HKLM. Since if first user use it and reset it and then other users wont be able to use it.
Only solution I can think of is writing that key in all the users but that is not working in case of windows 7.
You can't write to parts of the registry owned by other user's unless you have admin rights. If you can get admin rights, you would be much better using HKLM
. Even if you could iterate over HKEY_USERS
it is a brittle solution at best.
You probably don't want to require admin rights. In which case the registry does not have a place where non-admin users can store data to be shared between all users. Consequently you should save to a file in CSIDL_COMMON_APPDATA
.
On the other hand, perhaps what you are trying to achieve is to set a value at install time which users will pick up. If they then modify the setting in your app you want it saved under HKCU
. You can do this quite easily by writing your default settings to HKLM
. Then when your app reads the settings it first looks in HKCU
. If the setting is not present, it reads it out of HKLM
. The app always writes the values to HKCU
. Another variant is to build the default settings into the program rather than HKLM
which simplifies the installer.
The bottom line is that iterating of HKEY_USERS
is not a good solution to any problem that I can envisage.
The pattern used by all software that needs this facility is, HKLM is a read-only store of defaults, set at installation time.
At runtime, the software must always try to read from HKCU first, and fallback to HKLM if the HKCU data is not present, or stale. Regular users always write to HKCU, ensuring that their own settings track their own preferences.
Administrative tools can write to HKLM to change users defaults. It's a bit of work, but you can use explicit timestamp entries, saving the last time a value in the hive was changed, and use this to refresh HKCU from HKLM whenever HKLM has a fresher timestamp to cater for "system administrators" perhaps needing to be able to reset certain settings to different defaults.
HKEY_LOCAL_MACHINE\Software\YourPath
. It can be used on install time or by admin rights. Do you want to edit your key by every user and every time?
In this case: on install time create your key in HKEY_LOCAL_MACHINE\Software\YourPath
and specify a SECURITY_ATTRIBUTES
as MSDN library shows.
Is it your registry value? In that case, save it in HKEY_LOCAL_MACHINE so you only have one copy.
Otherwise, iterating over HKEY_USERS sounds good and will work on XP and Vista as well, as long as you have proper privileges to change the registry for other users.
SOLUTION: You save the key in HKLM in the installer. When a user reads it, it writes a separate key to HKCU, noting that it has used the shared key, so it won't read it the next time. Problem solved.
If you install some application which wait for the registry value in the HKCU part of the registry you can not choose any other registry place. So to customize the installed application one have to set HKCU part of all users which will work on the computer. It is the standard problem in the software deployment.
I find the best solution of the problem to use so named "Active Setup" about which you can read here or here. The advantage of the method is that it work not only with the local user profiles, but also with the roaming user profiles.
Maybe you can try to use Active Setup.
I have found a way to push a .reg file to all user hives in the reg. You need admin access and Powershell.
I use this in sccm so I wanted it to start from a .bat it uses a .reg to import current_user settings and a powershell script.
Powershellscript filename WriteToHkcuFromSystem.ps1
PARAM(
[Parameter(Mandatory=$true)] [ValidatePattern('\.reg$')] [string]$RegFile, [switch]$CurrentUser, [switch]$AllUsers, [switch]$DefaultProfile )
function Write-Registry { PARAM($RegFileContents) $tempFile = '{0}{1:yyyyMMddHHmmssff}.reg' -f [IO.Path]::GetTempPath(), (Get-Date) $RegFileContents | Out-File -FilePath $tempFile Write-Host ('Writing registry from file {0}' -f $tempFile) try { $p = Start-Process -FilePath C:\Windows\regedit.exe -ArgumentList "/s $tempFile" -PassThru -Wait } catch { } if($p -ne $null) { $exitCode = $p.ExitCode } else { $exitCode = 0 } if($exitCode -ne 0) { Write-Warning 'There was an error merging the reg file' } else { Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue } }
if(-not (Test-Path -Path $RegFile)) { Write-Warning "RegFile $RegFile doesn't exist. Operation aborted" } else {
if($CurrentUser -or $AllUsers -or $DefaultProfile) { Write-Host ('Reading the registry file {0}' -f $RegFile) $registryData = Get-Content -Path $RegFile -ReadCount 0 if($CurrentUser) { Write-Host "Writing to the currenlty loggoed on user's registry" $explorers = Get-WmiObject -Namespace root\cimv2 -Class Win32_Process -Filter "Name='explorer.exe'" $explorers | ForEach-Object { $owner = $_.GetOwner() if($owner.ReturnValue -eq 0) { $user = '{0}\{1}' -f $owner.Domain, $owner.User $ntAccount = New-Object -TypeName System.Security.Principal.NTAccount($user) $sid = $ntAccount.Translate([System.Security.Principal.SecurityIdentifier]).Value $RegFileContents = $registryData -replace 'HKEY_CURRENT_USER', "HKEY_USERS\$sid" Write-Registry -RegFileContents $RegFileContents } } } if($AllUsers) { Write-Host "Writing to every user's registry" $res = C:\Windows\system32\reg.exe query HKEY_USERS $res -notmatch 'S-1-5-18|S-1-5-19|S-1-5-20|DEFAULT|Classes' | ForEach-Object { if($_ -ne '') { $sid = $_ -replace 'HKEY_USERS\\' $RegFileContents = $registryData -replace 'HKEY_CURRENT_USER', "HKEY_USERS\$sid" Write-Registry -RegFileContents $RegFileContents } } } if($DefaultProfile) { Write-Host "Writing to the default profile's registry (for future users)" C:\Windows\System32\reg.exe load 'HKU\DefaultUser' C:\Users\Default\NTUSER.DAT | Out-Null $RegFileContents = $registryData -replace 'HKEY_CURRENT_USER', 'HKEY_USERS\DefaultUser' Write-Registry -RegFileContents $RegFileContents C:\Windows\System32\reg.exe unload 'HKU\DefaultUser' | Out-Null } } else { Write-Warning 'No mode was selected. Operation aborted' } }
bat filename addreg.bat
PowerShell.exe Set-ExecutionPolicy -ExecutionPolicy Unrestricted
PowerShell.exe -File "%~dp0WriteToHkcuFromsystem.ps1" -RegFile "%~dp0Example.reg" -CurrentUser -AllUsers -DefaultProfile
PowerShell.exe Set-ExecutionPolicy -ExecutionPolicy Restricted
and .reg file Example.reg
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\blabla] value=1 etc etc
精彩评论