2009-09-02 27 views
26

Tengo un servicio de Windows, escrito en C# y necesito ejecutar una aplicación de consola. aplicación de consola también escrito en C#.¿Cómo ejecutar la aplicación de consola desde el servicio de Windows?

La aplicación de consola se ejecuta correctamente cuando se ejecuta no desde el servicio de Windows. Cuando se ejecuta desde ws no hace nada que debería y como debería funcionar durante 10-20 segundos que veo en el código de depuración se ejecuta a la vez.

yo estoy empezando mi aplicación de consola con el siguiente código:

proc.Start(fullPathToConsole, args); 
proc.WaitForExit(); 

el camino de la consola es correcto y cuando yo estoy tratando de ejecutarlo desde el cmd o simplemente en el explorador (sin argumentos) se funciona bien. Pero después de correr con el servicio no veo ningún efecto.

ya que trataron de ir a las características del servicio y darle acceso al escritorio y se ejecutan bajo el sistema y mi usuario (también se especifica en las propiedades del servicio). Todo permanece igual.

ADEMÁS: Sé que el servicio no tienen interfaz de usuario y no quiero uno. Quiero que el servicio ejecute la aplicación de la consola. No es necesario obtener ningún dato o usar esta consola como ui, simplemente ejecutarlo para hacer su trabajo.

ACTUALIZACIÓN I: descubrí que la ejecución de calc o cualquier otra aplicación de Windows es fácil. Pero aún no se puede ejecutar cmd o cualquier aplicación de consola. En realidad, necesito ejecutarlo en XP SP2 y Windows 2003 Server. Por lo tanto, no es necesario que interactúes con Vista de todos modos.

Estaría encantado de hacer cualquier comentario!

+0

¿Cuál es el propósito de la ventana de la consola en relación con esta aplicación? Quizás si tuviéramos una idea del concepto de la aplicación podríamos proporcionar una solución más adecuada. – BenAlabaster

+0

en realidad no importa. El problema es que no puedo lanzarlo. Si sabe cómo abrir la consola con el servicio, publique el código. Las razones por las que necesito eso son demasiado largas. Sé que cuando necesitas una aplicación para ejecutar otra y esta otra hace algo diferente parece olor a arco, pero créanme, tengo razones para necesitar esto :-) –

+0

Tus razones para necesitarlo son irrelevantes. De Verdad. Microsoft siempre ha desaprobado los servicios que interactúan con el escritorio, pero desde que se inventó el ataque, decidieron desaprobar la capacidad y eliminarla por completo.Necesitarás encontrar una solución diferente. –

Respuesta

22

A partir de Windows Vista, un servicio no puede interactuar con el escritorio. No podrá ver ninguna ventana o ventanas de consola que se inicien desde un servicio. Vea esto MSDN forum thread.

En otro sistema operativo, no es una opción que está disponible en la opción de servicio llamado "Permitir a los servicios interactuar con el escritorio". Técnicamente, debe programar para el futuro y debe seguir la guía de Vista, incluso si no lo usa en Vista.

Si aún desea ejecutar una aplicación que no interactúe con el escritorio, intente especificar el proceso de no utilizar la cáscara.

ProcessStartInfo info = new ProcessStartInfo(@"c:\myprogram.exe"); 
info.UseShellExecute = false; 
info.RedirectStandardError = true; 
info.RedirectStandardInput = true; 
info.RedirectStandardOutput = true; 
info.CreateNoWindow = true; 
info.ErrorDialog = false; 
info.WindowStyle = ProcessWindowStyle.Hidden; 

Process process = Process.Start(info); 

Ver si esto soluciona el problema.

En primer lugar, informar a Windows que el programa no va a utilizar la cáscara (que es inaccesible en Vista al servicio).

En segundo lugar, permite redirigir todas las interacciones consolas de corriente interna (ver process.StandardInput y process.StandardOutput. Servicios

+0

No necesito ver nada. Todo lo que necesito es iniciar la aplicación de la consola, y hará el trabajo. Sé que el servicio no tiene ui etc. La pregunta es sobre cómo iniciar la consola desde la aplicación de servicio. –

+0

Entonces no lo llames una aplicación de consola. Una aplicación de consola tiene una interfaz de usuario, que es la consola. Intente cambiarlo a una aplicación de Windows, pero eso no muestra nada. –

+0

Tengo 2 aplicaciones: servicio y aplicación de consola. La aplicación de la consola funciona y no tiene interacción con el usuario. Así que escribí que no necesito ninguna interfaz de usuario para el servicio o para que la consola interactúe con el usuario, necesito iniciar la aplicación de consola para hacer su trabajo y necesito hacerlo desde mi servicio. ¿Qué dije mal? –

4

de Windows no tienen interfaces de usuario. Puede redirigir la salida de una aplicación de consola a su servicio con el código mostrado en this question.

+0

yo no necesito tener una interfaz de usuario o redirigir una salida. necesito lanzar una aplicación de consola y deja que haga el trabajo. yo no necesito ninguna interfaz de usuario, por lo que 's no la salida. –

0

Como dijo Pierre, no hay manera de tener una interfaz de usuario para un servicio de windows (o hay una manera fácil). lo que hago en ese tipo de situación es tener un archivo de configuración que se lee desde el servicio en cualquier intervalo en el que opera el servicio y tiene una aplicación independiente que realiza cambios en el archivo de configuración.

+0

por favor lea mis comentarios a otras respuestas, yo no necesito una interfaz de usuario para el servicio. –

0

¿Su aplicación de consola requiere interacción del usuario? Si es así, es un no-no serio y debería rediseñar su aplicación.Si bien hay algunos hacks para hacer este tipo de trabajo en versiones anteriores del sistema operativo, está garantizado que se romperá en el futuro.

Si su aplicación no requiere interacción con el usuario, entonces tal vez su problema está relacionado con el usuario del servicio se está ejecutando como. Intente asegurarse de que se ejecuta como el usuario correcto o de que el usuario y/o los recursos que está utilizando tienen los permisos adecuados.

Si necesita algún tipo de interacción con el usuario, deberá crear una aplicación cliente y comunicarse con el servicio y/o sub-aplicación a través de rpc, sockets o named pipes.

+0

no necesita interacción ed. Intenté la cuenta del sistema y mi cuenta de administrador. Creo que la cuenta de administrador debería estar lista para iniciar una aplicación de consola. –

0

servicios son necesarios para conectarse al control de servicios y proporcionar información en el arranque (es decir. SMC decir 'estoy vivo!'). Es por eso que la aplicación C# tiene una plantilla de proyecto diferente para los servicios. Tiene dos alternativas:

  • wrapp su exe en srvany.exe, tal como se describe en KB How To Create a User-Defined Service
  • tienen su aplicación de C# detectar cuando se presenta como un servicio y el interruptor de control a un (por ejemplo, línea de comando parámetro). clase que hereda de ServiceBase e implementa adecuadamente un servicio.
8

He hecho esto antes con éxito - Tengo un código en casa. Cuando llegue a casa esta noche, actualizaré esta respuesta con el código de trabajo de un servicio que inicia una aplicación de consola.

pensé que iba a tratar esto desde el principio. Aquí hay un código que escribí que inicia una aplicación de consola. Lo instalé como un servicio y lo ejecuté y funcionó correctamente: se inicia cmd.exe (como se ve en el Administrador de tareas) y vive durante 10 segundos hasta que le envíe el comando de salida. Espero que esto ayude a su situación, ya que funciona correctamente como se espera aquí.

using (System.Diagnostics.Process process = new System.Diagnostics.Process()) 
    { 
     process.StartInfo = new System.Diagnostics.ProcessStartInfo(@"c:\windows\system32\cmd.exe"); 
     process.StartInfo.CreateNoWindow = true; 
     process.StartInfo.ErrorDialog = false; 
     process.StartInfo.RedirectStandardError = true; 
     process.StartInfo.RedirectStandardInput = true; 
     process.StartInfo.RedirectStandardOutput = true; 
     process.StartInfo.UseShellExecute = false; 
     process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 
     process.Start(); 
     //// do some other things while you wait... 
     System.Threading.Thread.Sleep(10000); // simulate doing other things... 
     process.StandardInput.WriteLine("exit"); // tell console to exit 
     if (!process.HasExited) 
     { 
      process.WaitForExit(120000); // give 2 minutes for process to finish 
      if (!process.HasExited) 
      { 
       process.Kill(); // took too long, kill it off 
      } 
     } 
    } 
+0

¡Eso sería genial! Realmente impaciente waitnig !!! :-) –

0

Tengo un servicio de Windows, y añadí la siguiente línea en el constructor de mi servicio:

using System.Diagnostics; 
try { 
    Process p = Process.Start(@"C:\Windows\system32\calc.exe"); 
} catch { 
    Debugger.Break(); 
} 

Cuando traté de ejecutar esto, el Process.Start() se hizo la llamada, y no se produjo ninguna excepción. Sin embargo, la aplicación calc.exe no apareció. Para que funcione, edité las propiedades de mi servicio en el Administrador de control de servicios para permitir la interacción con el escritorio. Después de hacer eso, Process.Start() abrió calc.exe como se esperaba.

Pero, como otros han dicho, la interacción con el escritorio está mal visto por Microsoft y, esencialmente, se ha desactivado en Vista. Entonces, incluso si puede hacer que funcione en XP, no sé si podrá hacer que funcione en Vista.

-11

Ejecución de servicios de Windows cualquier aplicación, como por ejemplo ".exe" es raro que hacer porque el algoritmo no es tan eficaz.

+1

¿Por qué? Tenemos aplicaciones publicadas como aplicaciones de consola y servicios. Una aplicación de consola es mucho más fácil de depurar, por ejemplo. –

+0

declaraciones sin sentido la escritura es mucho menos eficaz – LastTribunal

+0

¿Cómo afectaría la eficacia algoritmo? –

0
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

using System.ServiceProcess; 
using System.Runtime.InteropServices; 

namespace SystemControl 
{ 
    class Services 
    { 
     static string strPath = @"D:\"; 
     static void Main(string[] args) 
     { 
      string strServiceName = "WindowsService1"; 
      CreateFolderStructure(strPath); 
      string svcPath = @"D:\Applications\MSC\Agent\bin\WindowsService1.exe"; 
      if (!IsInstalled(strServiceName)) 
      { 
       InstallAndStart(strServiceName, strServiceName, svcPath + " -k runservice");     
      } 
      else 
      { 
       Console.Write(strServiceName + " already installed. Do you want to Uninstalled the Service.Y/N.?"); 
       string strKey = Console.ReadLine(); 

       if (!string.IsNullOrEmpty(strKey) && (strKey.StartsWith("y")|| strKey.StartsWith("Y"))) 
       { 
        StopService(strServiceName); 
        Uninstall(strServiceName); 
        ServiceLogs(strServiceName + " Uninstalled.!", strPath); 
        Console.Write(strServiceName + " Uninstalled.!"); 
        Console.Read(); 
       } 
      } 
     } 

     #region "Environment Variables" 
     public static string GetEnvironment(string name, bool ExpandVariables = true) 
     { 
      if (ExpandVariables) 
      { 
       return System.Environment.GetEnvironmentVariable(name); 
      } 
      else 
      { 
       return (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment\").GetValue(name, "", Microsoft.Win32.RegistryValueOptions.DoNotExpandEnvironmentNames); 
      } 
     } 

     public static void SetEnvironment(string name, string value) 
     { 
      System.Environment.SetEnvironmentVariable(name, value); 
     } 
     #endregion 

     #region "ServiceCalls Native" 
     public static ServiceController[] List { get { return ServiceController.GetServices(); } } 

     public static void Start(string serviceName, int timeoutMilliseconds) 
     { 
      ServiceController service = new ServiceController(serviceName); 
      try 
      { 
       TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); 

       service.Start(); 
       service.WaitForStatus(ServiceControllerStatus.Running, timeout); 
      } 
      catch(Exception ex) 
      { 
       // ... 
      } 
     } 

     public static void Stop(string serviceName, int timeoutMilliseconds) 
     { 
      ServiceController service = new ServiceController(serviceName); 
      try 
      { 
       TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); 

       service.Stop(); 
       service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); 
      } 
      catch 
      { 
       // ... 
      } 
     } 

     public static void Restart(string serviceName, int timeoutMilliseconds) 
     { 
      ServiceController service = new ServiceController(serviceName); 
      try 
      { 
       int millisec1 = Environment.TickCount; 
       TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); 

       service.Stop(); 
       service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); 

       // count the rest of the timeout 
       int millisec2 = Environment.TickCount; 
       timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1)); 

       service.Start(); 
       service.WaitForStatus(ServiceControllerStatus.Running, timeout); 
      } 
      catch 
      { 
       // ... 
      } 
     } 

     public static bool IsInstalled(string serviceName) 
     { 
      // get list of Windows services 
      ServiceController[] services = ServiceController.GetServices(); 

      // try to find service name 
      foreach (ServiceController service in services) 
      { 
       if (service.ServiceName == serviceName) 
        return true; 
      } 
      return false; 
     } 
     #endregion 

     #region "ServiceCalls API" 
     private const int STANDARD_RIGHTS_REQUIRED = 0xF0000; 
     private const int SERVICE_WIN32_OWN_PROCESS = 0x00000010; 

     [Flags] 
     public enum ServiceManagerRights 
     { 
      Connect = 0x0001, 
      CreateService = 0x0002, 
      EnumerateService = 0x0004, 
      Lock = 0x0008, 
      QueryLockStatus = 0x0010, 
      ModifyBootConfig = 0x0020, 
      StandardRightsRequired = 0xF0000, 
      AllAccess = (StandardRightsRequired | Connect | CreateService | 
      EnumerateService | Lock | QueryLockStatus | ModifyBootConfig) 
     } 

     [Flags] 
     public enum ServiceRights 
     { 
      QueryConfig = 0x1, 
      ChangeConfig = 0x2, 
      QueryStatus = 0x4, 
      EnumerateDependants = 0x8, 
      Start = 0x10, 
      Stop = 0x20, 
      PauseContinue = 0x40, 
      Interrogate = 0x80, 
      UserDefinedControl = 0x100, 
      Delete = 0x00010000, 
      StandardRightsRequired = 0xF0000, 
      AllAccess = (StandardRightsRequired | QueryConfig | ChangeConfig | 
      QueryStatus | EnumerateDependants | Start | Stop | PauseContinue | 
      Interrogate | UserDefinedControl) 
     } 

     public enum ServiceBootFlag 
     { 
      Start = 0x00000000, 
      SystemStart = 0x00000001, 
      AutoStart = 0x00000002, 
      DemandStart = 0x00000003, 
      Disabled = 0x00000004 
     } 

     public enum ServiceState 
     { 
      Unknown = -1, // The state cannot be (has not been) retrieved. 
      NotFound = 0, // The service is not known on the host server. 
      Stop = 1, // The service is NET stopped. 
      Run = 2, // The service is NET started. 
      Stopping = 3, 
      Starting = 4, 
     } 

     public enum ServiceControl 
     { 
      Stop = 0x00000001, 
      Pause = 0x00000002, 
      Continue = 0x00000003, 
      Interrogate = 0x00000004, 
      Shutdown = 0x00000005, 
      ParamChange = 0x00000006, 
      NetBindAdd = 0x00000007, 
      NetBindRemove = 0x00000008, 
      NetBindEnable = 0x00000009, 
      NetBindDisable = 0x0000000A 
     } 

     public enum ServiceError 
     { 
      Ignore = 0x00000000, 
      Normal = 0x00000001, 
      Severe = 0x00000002, 
      Critical = 0x00000003 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     private class SERVICE_STATUS 
     { 
      public int dwServiceType = 0; 
      public ServiceState dwCurrentState = 0; 
      public int dwControlsAccepted = 0; 
      public int dwWin32ExitCode = 0; 
      public int dwServiceSpecificExitCode = 0; 
      public int dwCheckPoint = 0; 
      public int dwWaitHint = 0; 
     } 

     [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerA")] 
     private static extern IntPtr OpenSCManager(string lpMachineName, string lpDatabaseName, ServiceManagerRights dwDesiredAccess); 
     [DllImport("advapi32.dll", EntryPoint = "OpenServiceA", CharSet = CharSet.Ansi)] 
     private static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, ServiceRights dwDesiredAccess); 
     [DllImport("advapi32.dll", EntryPoint = "CreateServiceA")] 
     private static extern IntPtr CreateService(IntPtr hSCManager, string lpServiceName, string lpDisplayName, ServiceRights dwDesiredAccess, int dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lp, string lpPassword); 
     [DllImport("advapi32.dll")] 
     private static extern int CloseServiceHandle(IntPtr hSCObject); 
     [DllImport("advapi32.dll")] 
     private static extern int QueryServiceStatus(IntPtr hService, SERVICE_STATUS lpServiceStatus); 
     [DllImport("advapi32.dll", SetLastError = true)] 
     private static extern int DeleteService(IntPtr hService); 
     [DllImport("advapi32.dll")] 
     private static extern int ControlService(IntPtr hService, ServiceControl dwControl, SERVICE_STATUS lpServiceStatus); 
     [DllImport("advapi32.dll", EntryPoint = "StartServiceA")] 
     private static extern int StartService(IntPtr hService, int dwNumServiceArgs, int lpServiceArgVectors); 

     /// <summary> 
     /// Takes a service name and tries to stop and then uninstall the windows serviceError 
     /// </summary> 
     /// <param name="ServiceName">The windows service name to uninstall</param> 
     public static void Uninstall(string ServiceName) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr service = OpenService(scman, ServiceName, ServiceRights.StandardRightsRequired | ServiceRights.Stop | ServiceRights.QueryStatus); 
       if (service == IntPtr.Zero) 
       { 
        throw new ApplicationException("Service not installed."); 
       } 
       try 
       { 
        StopService(service); 
        int ret = DeleteService(service); 
        if (ret == 0) 
        { 
         int error = Marshal.GetLastWin32Error(); 
         throw new ApplicationException("Could not delete service " + error); 
        } 
       } 
       finally 
       { 
        CloseServiceHandle(service); 
       } 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Accepts a service name and returns true if the service with that service name exists 
     /// </summary> 
     /// <param name="ServiceName">The service name that we will check for existence</param> 
     /// <returns>True if that service exists false otherwise</returns> 
     public static bool ServiceIsInstalled(string ServiceName) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr service = OpenService(scman, ServiceName, 
       ServiceRights.QueryStatus); 
       if (service == IntPtr.Zero) return false; 
       CloseServiceHandle(service); 
       return true; 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Takes a service name, a service display name and the path to the service executable and installs/starts the windows service. 
     /// </summary> 
     /// <param name="ServiceName">The service name that this service will have</param> 
     /// <param name="DisplayName">The display name that this service will have</param> 
     /// <param name="FileName">The path to the executable of the service</param> 
     public static void InstallAndStart(string ServiceName, string DisplayName, 
     string FileName) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect | 
      ServiceManagerRights.CreateService); 
      try 
      { 
       string strKey = string.Empty; 
       IntPtr service = OpenService(scman, ServiceName, 
       ServiceRights.QueryStatus | ServiceRights.Start); 
       if (service == IntPtr.Zero) 
       { 
        service = CreateService(scman, ServiceName, DisplayName, 
        ServiceRights.QueryStatus | ServiceRights.Start, SERVICE_WIN32_OWN_PROCESS, 
        ServiceBootFlag.AutoStart, ServiceError.Normal, FileName, null, IntPtr.Zero, 
        null, null, null); 
        ServiceLogs(ServiceName + " Installed Sucessfully.!", strPath); 
        Console.Write(ServiceName + " Installed Sucessfully.! Do you want to Start the Service.Y/N.?"); 
        strKey=Console.ReadLine(); 
       } 
       if (service == IntPtr.Zero) 
       { 
        ServiceLogs("Failed to install service.", strPath); 
        throw new ApplicationException("Failed to install service."); 
       } 
       try 
       { 
        if (!string.IsNullOrEmpty(strKey) && (strKey.StartsWith("y") || strKey.StartsWith("Y"))) 
        { 
         StartService(service); 
         ServiceLogs(ServiceName + " Started Sucessfully.!", strPath); 
         Console.Write(ServiceName + " Started Sucessfully.!"); 
         Console.Read(); 
        } 
       } 
       finally 
       { 
        CloseServiceHandle(service); 
       } 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Takes a service name and starts it 
     /// </summary> 
     /// <param name="Name">The service name</param> 
     public static void StartService(string Name) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr hService = OpenService(scman, Name, ServiceRights.QueryStatus | 
       ServiceRights.Start); 
       if (hService == IntPtr.Zero) 
       { 
        ServiceLogs("Could not open service.", strPath); 
        throw new ApplicationException("Could not open service."); 
       } 
       try 
       { 
        StartService(hService); 
       } 
       finally 
       { 
        CloseServiceHandle(hService); 
       } 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Stops the provided windows service 
     /// </summary> 
     /// <param name="Name">The service name that will be stopped</param> 
     public static void StopService(string Name) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr hService = OpenService(scman, Name, ServiceRights.QueryStatus | 
       ServiceRights.Stop); 
       if (hService == IntPtr.Zero) 
       { 
        ServiceLogs("Could not open service.", strPath); 
        throw new ApplicationException("Could not open service."); 
       } 
       try 
       { 
        StopService(hService); 
       } 
       finally 
       { 
        CloseServiceHandle(hService); 
       } 



} 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Stars the provided windows service 
     /// </summary> 
     /// <param name="hService">The handle to the windows service</param> 
     private static void StartService(IntPtr hService) 
     { 
      SERVICE_STATUS status = new SERVICE_STATUS(); 
      StartService(hService, 0, 0); 
      WaitForServiceStatus(hService, ServiceState.Starting, ServiceState.Run); 
     } 

     /// <summary> 
     /// Stops the provided windows service 
     /// </summary> 
     /// <param name="hService">The handle to the windows service</param> 
     private static void StopService(IntPtr hService) 
     { 
      SERVICE_STATUS status = new SERVICE_STATUS(); 
      ControlService(hService, ServiceControl.Stop, status); 
      WaitForServiceStatus(hService, ServiceState.Stopping, ServiceState.Stop); 
     } 

     /// <summary> 
     /// Takes a service name and returns the <code>ServiceState</code> of the corresponding service 
     /// </summary> 
     /// <param name="ServiceName">The service name that we will check for his <code>ServiceState</code></param> 
     /// <returns>The ServiceState of the service we wanted to check</returns> 
     public static ServiceState GetServiceStatus(string ServiceName) 
     { 
      IntPtr scman = OpenSCManager(ServiceManagerRights.Connect); 
      try 
      { 
       IntPtr hService = OpenService(scman, ServiceName, 
       ServiceRights.QueryStatus); 
       if (hService == IntPtr.Zero) 
       { 
        return ServiceState.NotFound; 
       } 
       try 
       { 
        return GetServiceStatus(hService); 
       } 
       finally 
       { 
        CloseServiceHandle(scman); 
       } 
      } 
      finally 
      { 
       CloseServiceHandle(scman); 
      } 
     } 

     /// <summary> 
     /// Gets the service state by using the handle of the provided windows service 
     /// </summary> 
     /// <param name="hService">The handle to the service</param> 
     /// <returns>The <code>ServiceState</code> of the service</returns> 
     private static ServiceState GetServiceStatus(IntPtr hService) 
     { 
      SERVICE_STATUS ssStatus = new SERVICE_STATUS(); 
      if (QueryServiceStatus(hService, ssStatus) == 0) 
      { 
       ServiceLogs("Failed to query service status.", strPath); 
       throw new ApplicationException("Failed to query service status."); 
      } 
      return ssStatus.dwCurrentState; 
     } 

     /// <summary> 
     /// Returns true when the service status has been changes from wait status to desired status 
     /// ,this method waits around 10 seconds for this operation. 
     /// </summary> 
     /// <param name="hService">The handle to the service</param> 
     /// <param name="WaitStatus">The current state of the service</param> 
     /// <param name="DesiredStatus">The desired state of the service</param> 
     /// <returns>bool if the service has successfully changed states within the allowed timeline</returns> 
     private static bool WaitForServiceStatus(IntPtr hService, ServiceState 
     WaitStatus, ServiceState DesiredStatus) 
     { 
      SERVICE_STATUS ssStatus = new SERVICE_STATUS(); 
      int dwOldCheckPoint; 
      int dwStartTickCount; 

      QueryServiceStatus(hService, ssStatus); 
      if (ssStatus.dwCurrentState == DesiredStatus) return true; 
      dwStartTickCount = Environment.TickCount; 
      dwOldCheckPoint = ssStatus.dwCheckPoint; 

      while (ssStatus.dwCurrentState == WaitStatus) 
      { 
       // Do not wait longer than the wait hint. A good interval is 
       // one tenth the wait hint, but no less than 1 second and no 
       // more than 10 seconds. 

       int dwWaitTime = ssStatus.dwWaitHint/10; 

       if (dwWaitTime < 1000) dwWaitTime = 1000; 
       else if (dwWaitTime > 10000) dwWaitTime = 10000; 

       System.Threading.Thread.Sleep(dwWaitTime); 

       // Check the status again. 

       if (QueryServiceStatus(hService, ssStatus) == 0) break; 

       if (ssStatus.dwCheckPoint > dwOldCheckPoint) 
       { 
        // The service is making progress. 
        dwStartTickCount = Environment.TickCount; 
        dwOldCheckPoint = ssStatus.dwCheckPoint; 
       } 
       else 
       { 
        if (Environment.TickCount - dwStartTickCount > ssStatus.dwWaitHint) 
        { 
         // No progress made within the wait hint 
         break; 
        } 
       } 
      } 
      return (ssStatus.dwCurrentState == DesiredStatus); 
     } 

     /// <summary> 
     /// Opens the service manager 
     /// </summary> 
     /// <param name="Rights">The service manager rights</param> 
     /// <returns>the handle to the service manager</returns> 
     private static IntPtr OpenSCManager(ServiceManagerRights Rights) 
     { 
      IntPtr scman = OpenSCManager(null, null, Rights); 
      if (scman == IntPtr.Zero) 
      { 
       try 
       { 
        throw new ApplicationException("Could not connect to service control manager."); 
       } 
       catch (Exception ex) 
       { 
       } 
      } 
      return scman; 
     } 

     #endregion 

     #region"CreateFolderStructure" 
     private static void CreateFolderStructure(string path) 
     { 
      if(!System.IO.Directory.Exists(path+"Applications")) 
       System.IO.Directory.CreateDirectory(path+ "Applications"); 
      if (!System.IO.Directory.Exists(path + "Applications\\MSC")) 
       System.IO.Directory.CreateDirectory(path + "Applications\\MSC"); 
      if (!System.IO.Directory.Exists(path + "Applications\\MSC\\Agent")) 
       System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\Agent"); 
      if (!System.IO.Directory.Exists(path + "Applications\\MSC\\Agent\\bin")) 
       System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\Agent\\bin"); 
      if (!System.IO.Directory.Exists(path + "Applications\\MSC\\AgentService")) 
       System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\AgentService"); 

      string fullPath = System.IO.Path.GetFullPath("MSCService"); 
      if (System.IO.Directory.Exists(fullPath)) 
      { 
       foreach (string strFile in System.IO.Directory.GetFiles(fullPath)) 
       { 
        if (System.IO.File.Exists(strFile)) 
        { 
         String[] strArr = strFile.Split('\\'); 
         System.IO.File.Copy(strFile, path + "Applications\\MSC\\Agent\\bin\\"+ strArr[strArr.Count()-1], true); 
        } 
       } 
      }    
     } 
     #endregion 

     private static void ServiceLogs(string strLogInfo, string path) 
     { 
      string filePath = path + "Applications\\MSC\\AgentService\\ServiceLogs.txt";    
      System.IO.File.AppendAllLines(filePath, (strLogInfo + "--" + DateTime.Now.ToString()).ToString().Split('|')); 
     } 
    } 
} 
+0

Intente agregar comentarios útiles con su código para describir lo que está haciendo y cómo resuelve el problema en lugar de solo publicar el código. –

+1

Si bien este código puede responder a la pregunta, proporcionar un contexto adicional con respecto a por qué y/o cómo responde este código a la pregunta mejora su valor a largo plazo. – JAL

Cuestiones relacionadas