我正在尝试在注销时修改 HKCU 中的注册表项。手动调用时,相应的脚本可以正常工作。我担心环回策略可能会出现问题,但根据 rsop.msc 的说法,情况并非如此,即脚本应该执行。但是,下次登录时注册表中不会出现预期的效果。
是否仅仅因为脚本运行“太晚”而存在一般问题?如果是,该怎么办?还能是什么原因?
编辑:
我应该指定我的logoff.vbs
脚本的样子(最小化):
const HKCU = &H80000001
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
' ...
oReg.SetStringValue HKCU,"SOFTWARE\Foo","Bar", "Baz"
答案1
我经常使用注销脚本。脚本运行时仍会加载用户的注册表,并且可以对其注册表进行修改。注销脚本按照设计同步运行。我有从用户注册表读取的注销脚本,但我从未有机会编写它。即便如此,我还是希望它能正常工作。
我把上面的代码片段放在一个文件中,并将其指定为 Windows XP SP3 VM 上本地组策略中的注销脚本,并获得了所需的结果。我将其设置HKCU\Software\Foo\Bar
为xxx
,注销,再次登录,发现值已更改为Baz
,正如预期的那样。
我认为除了脚本执行之外,您还遇到了其他问题。我添加了MsgBox
对代码的调用,以便我可以“看到”注销时运行的代码。添加 MsdBox 并没有改变与注册表相关的行为,但确实给了我代码正在运行的视觉指示(并且直到我关闭对话框时才停止注销)。
(如果您愿意,我也可以继续在 Windows 7 上进行测试,但我预计功能不会发生任何变化。)
答案2
我猜想您是在使用它reg.exe
来修改注册表项。问题是它reg.exe
在单独的进程中运行,并且注销脚本只等待自身完成。因此,注册表配置单元很可能在编辑完成之前就被卸载了。
我认为您可以使用两行 WScript 解决这个问题,如以下示例所示:
Set objShell = CreateObject("WScript.Shell")
objShell.Run "REG ADD HKCU\key ...",,true
的第三个参数objShell.Run
称为bWaitOnReturn
,告诉脚本等待外部进程完成后再继续执行。
答案3
事实上二问题。
首先,在存在环回策略的情况下,必须小心使用 rsop.msc,因为仅使用默认值(即在选择用户和计算机容器后立即勾选“跳转到向导的最后一页而不收集更多数据”)可能无法反映真正的策略结果。必须至少在第二页勾选环回(并替换或合并)才能获得真实的结果。在这里小心谨慎有助于诊断正确地脚本是否会在注销时运行。
其次,SetStringValue
如果之前不存在价值,就会创造价值,但确实存在不是创建不存在的密钥。因此,
oReg.CreateKey HKCU,"SOFTWARE\Foo"
必须在剧本中发布(记录在案,CreateKey
做递归创建不存在的键,但“HKCU\SOFTWARE”当然已经存在)。