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