Проблемы с VBScript - RegRead при запуске в качестве службы - PullRequest
1 голос
/ 04 февраля 2010

Я работаю над сценарием, который запускается под специальной утилитой установки, которая работает как служба.Чтобы получить текущее имя пользователя, скрипт выполняет следующую команду:

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 я мог бы найти текущего пользователя?

Ответы [ 3 ]

0 голосов
/ 05 февраля 2010

Если ваш процесс работает как сервис, как «ЛОКАЛЬНАЯ СИСТЕМА», то он действительно вернет «СИСТЕМУ» в качестве текущего пользователя. HKCU в начале раздела реестра означает HKEY_CURRENT_USER, который будет "SYSTEM".

Поскольку в Windows может быть зарегистрировано несколько пользователей, даже в «потребительских» версиях (благодаря быстрому переключению пользователей), насколько мне известно, нет надежного способа определить, кто является «текущим» пользователем. В зависимости от того, как вызывается служба установщика, вы можете попробовать что-то вроде запуска процесса при запуске для каждого пользователя (т. Е. В разделе «Автозагрузка программ» в меню «Пуск»), который регистрируется в службе, чтобы сообщить ему, какое имя в данный момент зарегистрировано. Пользователь есть. Этот процесс, вероятно, может также связываться со службой, когда пользователь быстро переключается с данного пользователя, поэтому он также может обрабатывать случай, когда на компьютере зарегистрировано более одного пользователя.

0 голосов
/ 07 февраля 2010

Если вы полны решимости получить информацию из реестра, вам придется сканировать ключи в HKEY_USERS (кроме .DEFAULT и * _ Classes ), чтобы узнать пользователей, профили загружены и кто при этом залогинен. Кстати, так работает инструмент SysInternals PsLoggedOn ; вы можете взглянуть на его исходный код ( Archive.org имеет его ), чтобы получить идею.

В качестве альтернативы, если вы можете использовать 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
0 голосов
/ 05 февраля 2010

Хм, интересно, сработает ли команда Windows Scripting Host для текущего пользователя, вошедшего в систему. Я бы подумал, что это сработает, даже если позвонить с учетной записи службы.

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