2010-01-18 20 views
22

Estoy tratando de iniciar una aplicación .NET bajo un usuario diferente de un servicio .NET. La idea es crear una aplicación de alojamiento de espacio aislado en Windows. En el servicio, creé programáticamente el usuario en Windows, creé una carpeta para ese usuario y descargué el .exe del host de un servidor en esa carpeta. Luego ejecuto el host .exe usando System.Diagnostics.Process. Aquí está el StartInfo para el proceso:¿Problema de permisos al iniciar la aplicación .NET del servicio .NET como un usuario diferente?

_process = new Process 
{ 
    StartInfo = 
    { 
     Arguments = " -debug", 
     FileName = instanceDirectory + "host.exe", 
     WorkingDirectory = instanceDirectory, 
     UseShellExecute = false, 
     RedirectStandardError = true, 
     RedirectStandardOutput = true, 
     RedirectStandardInput = true, 
     UserName = Helpers.GetUserNameForInstance(_hostid), 
     Password = _hostpass, 
     Domain = "" 
    }, 
    EnableRaisingEvents = true 
}; 

Cuando ejecuto el servicio como un servicio, el proceso se bloquea al instante con un código de error -1073741502. pero cuando ejecuto el servicio como el mismo usuario especificado en el servicio de Windows pero interactivamente en la consola, todo funciona bien. Esto solo ocurre cuando se ejecuta el servicio como un SERVICIO y no directamente en la consola.

Cualquier ayuda sería MUCHO apreciada. Este ha sido un dolor de cabeza durante mucho tiempo y este es el último recurso :(

+0

ha probado el mismo código que se ejecuta en una aplicación de consola? –

+2

sí, todo funciona bien en el modo independiente ... solo tiene problemas para ejecutarse como servicio. –

+1

Hola, Como dices, parece un problema de permiso porque se ejecuta cuando no es un servicio. Este enlace puede ayudar: http://asprosys.blogspot.com/2009/03/perils-and-pitfalls-of-launching.html – keyboardP

Respuesta

1

0xc0000142 (-1073741502) se STATUS_DLL_INIT_FAILED:.

inicialización de la biblioteca de enlace dinámico [nombre] falló el proceso termina de forma anormal

.

Como señaló el sitio web TenaciousImpy, debe otorgar permisos de cuenta a la estación de ventana y al escritorio. Pero si el programa es interactivo, también debe establecer la identificación de sesión del token de proceso.

14

Parece que el uso de la new Process() con un nombre de usuario y contraseña y el modo de servicio "no computa" :)

Presupuesto de MSDN:

Puede cambiar los parámetros especificados en el La propiedad StartInfo hasta hasta el momento en que llame al método Start en el proceso. Después de iniciar el proceso, cambiar los valores de StartInfo no afecta ni reinicia el proceso asociado . Si se llama al método Inicio (ProcessStartInfo) con la ProcessStartInfo .. ::. Nombre de usuario y ProcessStartInfo .. ::. contraseña propiedades determinan, la función CreateProcessWithLogonW no administrado es llamada, que se inicia el proceso de una nueva ventana incluso si el valor de propiedad CreateNoWindow es verdadero o el valor de propiedad WindowStyle es Oculto.

Además, mirando a la documentación CreateProcessWithLogonW:

lpStartupInfo [en]

Un puntero a una estructura STARTUPINFO.La aplicación debe agregar el permiso para la cuenta de usuario especificada a la ventana especificada estación y escritorio, incluso para WinSta0 \ Default.

Si el miembro de lpDesktop es NULL o una cadena vacía, el nuevo proceso hereda la estación de escritorio y ventana de su proceso principal. La aplicación debe agregar permiso para la cuenta de usuario especificada a la estación de ventana heredada y al escritorio.

No hay lpDesktop en .NET STARTUPINFO, por el contrario el usuario del servicio no tiene escritorio, lo que podría causar su problema.

Para resumir, tratan de establecer el LoadUserProfile a true para cargar la información del usuario del registro, o tal vez lo que necesita para establecer el directorio de trabajo, etc.

Para investigar más a fondo, su debe comprobar su entorno y tal vez registrar a qué archivos se accede utilizando FileMon.

5

Intentaré crear el proceso en el contexto suplantado del usuario recién creado, como se muestra a continuación.

[DllImport("advapi32.DLL", SetLastError = true)] 
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
public extern static bool CloseHandle(IntPtr handle); 

[DllImport("advapi32.DLL")] 
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); 

static void Main() 
{    
    IntPtr admin_token = new IntPtr(); 
    WindowsIdentity wid_admin = null; 
    WindowsImpersonationContext wic = null; 

    LogonUser("username", "domain", "password", 9, 3, out admin_token); 
    wid_admin = new WindowsIdentity(admin_token); 
    wic = wid_admin.Impersonate(); 

    _process = new Process 
    { 
     StartInfo = 
     { 
      Arguments = " -debug", 
      FileName = instanceDirectory + "host.exe", 
      WorkingDirectory = instanceDirectory, 
      UseShellExecute = false, 
      RedirectStandardError = true, 
      RedirectStandardOutput = true, 
      RedirectStandardInput = true, 
      UserName = Helpers.GetUserNameForInstance(_hostid), 
      Password = _hostpass, 
      Domain = "" 
     }, 
     EnableRaisingEvents = true 
    }; 

    if (wic != null) wic.Undo(); 
    CloseHandle(admin_token); 
} 
+0

Lo intenté y no pareció ayudar. Refiriéndonos a lo que Gyuri citó, parece que el usuario necesita permiso para usar la estación de ventana y el escritorio al que pertenece el servicio. – jamessan

Cuestiones relacionadas