En general, para arrancar un nuevo proceso desde una aplicación en C# usamos la clase "Process". El proceso nuevo se ejecutará con el mismo usuario que el proceso padre sin problemas.
Sin embargo, cuando queremos arrancar el mismo proceso en el servidor desde una aplicación web surge un problema: Todas las aplicaciones ASP.NET se ejecutan por defecto con el usuario ASPNET (o NETWORK_SERVICE en Windows 2003), que tiene permisos limitados para acceder a ficheros y no puede interactuar con el escritorio.
Una primera solución podría ser utilizar el impersonate de ASP.NET para cambiar el usuario con el que se ejecuta el servicio web y después arrancar el nuevo proceso. Sin embargo, el impersonate sólo cambia el usuario a nivel de hilo y el nuevo proceso se ejecutará con el mismo usuario que el proceso padre, con lo cual el proceso nuevo se seguiría ejecutando con el usuario ASPNET.
La clase Process en el Framework .NET 2.0 ya soluciona este problema y permite especificar el usuario con el que se ejecutará el nuevo proceso. Para resolverlo con el Framework 1.1 de .NET podemos cambiar el usuario con el que se ejecutan por defecto todas las aplicaciones ASP.NET de la siguiente forma:
- Abrimos el fichero machine.config que se debería encontrar en "C:\WINDOWS\Microsoft.NET\Framework\{versión}\CONFIG\".
- Localizamos la etiqueta processModel:
<processModel enable="true" timeout="Infinite" idleTimeout="Infinite" shutdownTimeout="0:00:05" requestLimit="Infinite" requestQueueLimit="5000" restartQueueLimit="10" memoryLimit="60" webGarden="false" cpuMask="0xffffffff" userName="machine" password="AutoGenerate" logLevel="Errors" clientConnectedCheck="0:00:05" comAuthenticationLevel="Connect" comImpersonationLevel="Impersonate" responseDeadlockInterval="00:03:00" maxWorkerThreads="20" maxIoThreads="20"/>
- Cambiamos "machine" en el parámetro userName por "SYSTEM".
- Reiniciamos y listo.
De esta forma, el usuario por defecto ahora será SYSTEM y no ASPNET. En su lugar, también podríamos haber especificado el nombre de usuario y contraseña de cualquier otra cuenta de usuario disponible con otros privilegios.
A pesar de que todas las aplicaciones se ejecuten ahora con el usuario SYSTEM, si arrancamos un nuevo programa a través del servicio web sólo vamos a poder ver que está ejecutándose a través del administrador de tareas de Windows ya que por defecto IIS no tiene habilitados los permisos para interactuar con el escritorio.
Si queremos ver la ventana o la consola del programa que hemos arrancado tenemos que permitir que el IIS interactúe con el escritorio. Lo haremos de la siguiente forma:
- En "Settings -> Control Panel -> Administrative Tools -> Services" abrimos las propiedades del servicio "IIS Admin".
- En la pestaña "Log On" activamos la opción "Allow service to interact with desktop".
- Reiniciamos el servicio y ya está.
En estos momentos ya estamos en disposición de ejecutar cualquier proceso de forma remota en una máquina a través de un servicio web alojado en ella. Ya sólo nos queda crear el servicio web. Para ello, utilizaremos el siguiente método web, sin olvidarnos de incluir el namespace System.Diagnostics para poder utilizar la clase Process:
... 1 using System.Diagnostics; ... 2 [WebMethod (Description="Descripción del método")] 3 public int Launch(string program, string parameters) { 4 Process proceso = new Process(); 5 try { 6 proceso.StartInfo.FileName = program; 7 if (parameters != "") { 8 proceso.StartInfo.Arguments = parameters; 9 } 10 proceso.Start(); 11 proceso.WaitForExit(); 12 return proceso.ExitCode; 13 } 14 catch {} 15 }
El método recibe como parámetros la ruta completa del ejecutable y los parámetros que queremos que reciba.