还有其他解决方案可用于XP、VISTA以及Windows 7吗?
实际上,安装程序需要将一个键写入注册表。而且该键需要被所有用户使用。一旦使用,键就应该被重置。
如果我们只在HKLM中保留一个键的副本,这是无法完成的。因为如果第一个用户使用它并重置它,那么其他用户就无法使用它。
我能想到的唯一解决方案是将该键写入所有用户,但在Windows 7的情况下无法工作。
HKLM
。即使您可以遍历HKEY_USERS
,这也是一个脆弱的解决方案。CSIDL_COMMON_APPDATA
中的文件。HKCU
下。您可以通过将默认设置写入HKLM
来轻松实现此目标。然后,当您的应用程序读取设置时,它首先查找HKCU
。如果该设置不存在,则从HKLM
中读取。该应用程序始终将值写入HKCU
。另一种变体是将默认设置构建到程序中,而不是HKLM
,这简化了安装程序。HKEY_USERS
不是我能想象的任何问题的好解决方案。我找到了一种方法,可以将.reg文件推送到注册表中的所有用户蜂房。您需要管理员访问权限和Powershell。
我在sccm中使用它,所以我希望它从.bat开始,它使用.reg导入当前用户设置和一个powershell脚本。
Powershell脚本文件名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文件名为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
以及.reg文件Example.reg
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\blabla] value=1等等
这是你的注册表值吗?如果是,将其保存在HKEY_LOCAL_MACHINE中,这样你只有一份副本。
否则,遍历HKEY_USERS听起来不错,并且在XP和Vista上也可以工作,只要你有适当的权限更改其他用户的注册表。
解决方案:在安装程序中将键保存在HKLM中。当用户读取它时,它会将一个单独的键写入HKCU,指示它已经使用了共享键,因此下次不会再读取它。问题得到解决。
HKEY_USERS
是行不通的,因为你需要管理员权限。 - David HeffernanHKEY_LOCAL_MACHINE\Software\YourPath
。它可以在安装时或通过管理员权限使用。您想让每个用户每次都编辑您的密钥吗?
在这种情况下:在安装时创建您的密钥HKEY_LOCAL_MACHINE\Software\YourPath
并指定一个SECURITY_ATTRIBUTES
,如MSDN库所示。
所有需要此功能的软件使用的模式是,HKLM 是一个只读的默认存储区,在安装时设置。
在运行时,软件必须始终首先尝试从 HKCU 读取,并在 HKCU 数据不存在或过期时回退到 HKLM。普通用户总是写入 HKCU,确保其自己的设置跟踪其自己的偏好。
管理工具可以写入 HKLM 来更改用户的默认设置。这需要一些工作,但您可以使用显式时间戳条目,保存 hive 中的值最后更改的时间,并使用此来从 HKLM 刷新 HKCU,每当 HKLM 具有更新的时间戳以满足“系统管理员”可能需要能够将某些设置重置为不同的默认值。
或许你可以尝试使用Active Setup。