VBScript 的问题 - 作为服务运行时的 RegRead

Posted

技术标签:

【中文标题】VBScript 的问题 - 作为服务运行时的 RegRead【英文标题】:Problems with VBScript - RegRead when running as a service 【发布时间】:2010-02-04 15:09:23 【问题描述】:

我正在编写一个在自定义安装实用程序下运行的脚本,该实用程序作为服务运行。要获取当前用户名,脚本执行以下命令:

str_Acct_Name_Val = "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Logon User Name"
str_Acct_Name = RegRead(str_Acct_Name_Val)

当我从命令提示符运行脚本时,它可以很好地读取该值(在管理员帐户下)。当尝试使用服务/本地系统权限读取该值时,读取失败。

这里有什么问题?

编辑:一些附加信息。当作为调用当前用户名的服务运行时返回“SYSTEM”,我的猜测是 HKCU 在 SYSTEM 视图下不“存在”,因为从技术上讲没有当前用户。当时有用户登录,但不在运行脚本的范围内。也许在 HKLM 的某个地方我可以找到当前登录的用户?

【问题讨论】:

【参考方案1】:

如果您确定要从注册表中获取信息,则必须扫描 HKEY_USERS 下的键(.DEFAULT*_Classes 除外)以找出已加载配置文件并因此登录的用户。顺便说一下,这就是 SysInternals PsLoggedOn 工具的工作原理;你可以看看它的源代码 (Archive.org has it) 来了解一下。

或者,如果您可以使用 WMI,您可以通过枚举Win32_LogonSession 类实例并检索关联的Win32_Account 对象来获取已登录用户的列表;像这样:

strComputer = "."

Set oWMI = GetObject("winmgmts:impersonationLevel=impersonate!\\" & strComputer & "\root\cimv2") 

Set colSessions = oWMI.ExecQuery _ 
    ("SELECT * FROM Win32_LogonSession WHERE LogonType = 2")  ' Interactive sessions only

For Each oSession in colSessions 
  Set colAccounts = oWMI.ExecQuery("ASSOCIATORS OF Win32_LogonSession.LogonId=" & oSession.LogonId & " " _ 
    & "WHERE AssocClass=Win32_LoggedOnUser Role=Dependent" ) 
  For Each oAccount in colAccounts
    WScript.Echo "Caption: " & oAccount.Caption
    WScript.Echo "Domain: "  & oAccount.Domain
    WScript.Echo "Name: "    & oAccount.Name
  Next 
Next

还有一个 Win32ComputerSystem.UserName 属性保存其桌面当前处于活动状态的登录用户的名称:

strComputer = "." 
Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set colItems = oWMI.ExecQuery("SELECT * FROM Win32_ComputerSystem") 
For Each objItem in colItems 
  Wscript.Echo objItem.UserName
Next

【讨论】:

【参考方案2】:

Hrm,我想知道对当前登录的用户使用 Windows Scripting Host 命令是否可行。我认为即使从服务帐户调用它也会起作用。

Set WSHNetwork = CreateObject("WScript.Network")    
strUSERID = UCase(WSHNetwork.UserName)

【讨论】:

【参考方案3】:

如果您的进程作为服务运行,作为“本地系统”,那么它确实会以当前用户的身份返回“系统”。注册表项开头的 HKCU 表示 HKEY_CURRENT_USER,即“SYSTEM”。

由于 Windows 可以有多个用户登录,即使在“消费者级别”版本(感谢快速用户切换)上,据我所知,没有可靠的方法来确定“当前”用户是谁。根据安装程序服务的调用方式,您可以尝试让每个用户在启动时运行一个进程(即在“开始”菜单中的“启动程序”中),该进程向该服务注册以告诉它当前登录的名称是什么用户是。当该用户被快速用户切换离开时,此过程可能还可以与服务通信,因此它还可以处理多个用户登录机器的情况。

【讨论】:

以上是关于VBScript 的问题 - 作为服务运行时的 RegRead的主要内容,如果未能解决你的问题,请参考以下文章

ui 和服务器脚本作为一个脚本运行,运行良好。但是在不同的文件 ui.R 和 server.R 中运行脚本会引发错误

在 VBscript 中绘制图形

当设置为“是不是登录时运行”时,Windows 任务计划程序不运行 VBScript

从自身以管理员身份运行 vbscript (Nagios / NSclient)

配置子管理员时的 Sonata Bundle 错误

ORA-12560:TSN:服务运行时的协议适配器错误