为所有用户设置注册表值

3
什么是在计算机上为所有用户设置注册表值的最佳方法?枚举HKEY_USERS并更改ntuser.dat是一种解决方案。
还有其他解决方案可用于XP、VISTA以及Windows 7吗?
实际上,安装程序需要将一个键写入注册表。而且该键需要被所有用户使用。一旦使用,键就应该被重置。
如果我们只在HKLM中保留一个键的副本,这是无法完成的。因为如果第一个用户使用它并重置它,那么其他用户就无法使用它。
我能想到的唯一解决方案是将该键写入所有用户,但在Windows 7的情况下无法工作。
7个回答

7
除非您拥有管理员权限,否则无法写入其他用户拥有的注册表部分。如果您可以获得管理员权限,最好使用HKLM。即使您可以遍历HKEY_USERS,这也是一个脆弱的解决方案。
您可能不想要求管理员权限。在这种情况下,注册表没有一个地方可以让非管理员用户存储要在所有用户之间共享的数据。因此,您应该保存到CSIDL_COMMON_APPDATA中的文件。
另一方面,也许您正在尝试在安装时设置一个值,用户将在其中选择。如果他们随后修改了您的应用程序中的设置,则希望将其保存在HKCU下。您可以通过将默认设置写入HKLM来轻松实现此目标。然后,当您的应用程序读取设置时,它首先查找HKCU。如果该设置不存在,则从HKLM中读取。该应用程序始终将值写入HKCU。另一种变体是将默认设置构建到程序中,而不是HKLM,这简化了安装程序。
底线是,迭代HKEY_USERS不是我能想象的任何问题的好解决方案。

但安装程序通常在管理员权限下运行,因此我猜应该可以将数据写入其他用户的注册表中。 - anand
@Alien01 当你添加一个新用户的时候,它就会失败。 - David Heffernan
@Alien01 我们都在猜测一些东西,因为你没有详细说明你的问题。你能否提供更多关于这些设置的细节,是谁更改它们,它们是每台机器还是每个用户的设置。 - David Heffernan

0

我找到了一种方法,可以将.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等等


0

这是你的注册表值吗?如果是,将其保存在HKEY_LOCAL_MACHINE中,这样你只有一份副本。

否则,遍历HKEY_USERS听起来不错,并且在XP和Vista上也可以工作,只要你有适当的权限更改其他用户的注册表。

解决方案:在安装程序中将键保存在HKLM中。当用户读取它时,它会将一个单独的键写入HKCU,指示它已经使用了共享键,因此下次不会再读取它。问题得到解决。


我尝试了迭代解决方案。在VISTA和XP上运行良好,但在Windows 7上,在尝试在HKEY_USERS中创建键时出现访问被拒绝的错误。 - anand
在问题部分添加了更多信息。 - anand
迭代HKEY_USERS是行不通的,因为你需要管理员权限。 - David Heffernan

0

HKEY_LOCAL_MACHINE\Software\YourPath。它可以在安装时或通过管理员权限使用。您想让每个用户每次都编辑您的密钥吗?

在这种情况下:在安装时创建您的密钥HKEY_LOCAL_MACHINE\Software\YourPath并指定一个SECURITY_ATTRIBUTES,如MSDN库所示。


是的,我们需要每个用户和每次编辑都能够进行编辑...所以不能将其保存在HKLM中。 - anand
哦,设置了一个HKLM注册表键的宽松ACL。你的客户系统管理员不会喜欢这个。 - David Heffernan

0

所有需要此功能的软件使用的模式是,HKLM 是一个只读的默认存储区,在安装时设置。

在运行时,软件必须始终首先尝试从 HKCU 读取,并在 HKCU 数据不存在或过期时回退到 HKLM。普通用户总是写入 HKCU,确保其自己的设置跟踪其自己的偏好。

管理工具可以写入 HKLM 来更改用户的默认设置。这需要一些工作,但您可以使用显式时间戳条目,保存 hive 中的值最后更改的时间,并使用此来从 HKLM 刷新 HKCU,每当 HKLM 具有更新的时间戳以满足“系统管理员”可能需要能够将某些设置重置为不同的默认值。


0

或许你可以尝试使用Active Setup。


0

如果您安装了某些等待注册表值在注册表的HKCU部分中的应用程序,则无法选择任何其他注册表位置。因此,要自定义安装的应用程序,必须设置所有用户的HKCU部分,这些用户将在计算机上工作。这是软件部署中的标准问题。

我发现解决该问题的最佳方案是使用所谓的“Active Setup”,您可以在此处此处阅读相关资料。该方法的优点是它不仅适用于本地用户配置文件,还适用于漫游用户配置文件


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接