Pregunta

Estoy trabajando en un script que se ejecuta bajo una utilidad de instalación personalizada, que se ejecuta como un servicio. Para obtener el nombre de usuario actual, el script ejecuta este comando:

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

Cuando ejecuto el script desde el símbolo del sistema, puede leer ese valor bien (en una cuenta de administrador). Cuando se intenta leer el valor con los privilegios de servicio/sistema local, la lectura falla.

¿Cuál es el problema aquí?

Editar: información adicional. Cuando se ejecuta como un servicio que llama al nombre de usuario actual, devuelve "sistema" y supongo que HKCU no "existe" bajo la vista del sistema, ya que técnicamente no hay usuario actual. Hay un usuario que inició sesión en ese momento, pero no en el alcance del script en ejecución. ¿Tal vez hay en algún lugar en HKLM, podría encontrar el usuario que se registra actualmente?

¿Fue útil?

Solución

Si está decidido a obtener información del registro, deberá escanear las claves en HKEY_USERS (excepto .DEFECTO y *_Classes) para averiguar a los usuarios cuyos perfiles están cargados y que se registran así. Así es como el sistema de sysinternals Psloggedon La herramienta funciona, por cierto; Puede echar un vistazo a su código fuente (Archive.org lo tiene) para obtener la idea.

Alternativamente, si puede usar WMI, puede obtener la lista de los usuarios registrados en enumerar el Win32_LogonSession instancias de clase y recuperar lo asociado Win32_Account objetos; algo como esto:

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

También está el Win32ComputerSystem.UserName Propiedad que contiene el nombre del usuario registrado cuyo escritorio está actualmente activo:

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

Otros consejos

HRM, me pregunto si funcionaría para usar el comando de host Windows Scripting para el usuario que se registra actualmente. Creo que eso funcionaría incluso si se le llame desde una cuenta de servicio.

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

Si su proceso se está ejecutando como un servicio, como "sistema local", entonces devolverá el "sistema" como el usuario actual. El HKCU al comienzo de la clave de registro significa HKEY_CURRENT_USER, que será "sistema".

Como Windows puede tener múltiples usuarios que iniciarían sesión, incluso en versiones de "nivel de consumidor" (gracias al cambio rápido de usuarios), no hay una forma confiable de determinar quién es el usuario "actual", que yo sepa. Dependiendo de cómo se invoque el servicio del instalador, podría probar algo como tener un proceso que se ejecute en el inicio de cada usuario (es decir, los programas de inicio en el menú de inicio) que se registra con el servicio para decirle el nombre del nombre de la sesión actualmente iniciada. El usuario es. Este proceso probablemente también podría comunicarse con el servicio cuando ese usuario se desvía del usuario rápido, por lo que también puede manejar el caso en el que más de un usuario se registra en la máquina.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top