Pregunta

¿Cuál es la mejor manera en C # para configurar una aplicación de utilidad que se puede ejecutar desde la línea de comandos y producir algún resultado (o escribir en un archivo), pero que también podría ejecutarse como un servicio de Windows para hacer su trabajo? en segundo plano (por ejemplo, monitorear un directorio, o lo que sea).

Me gustaría escribir el código una vez y poder llamarlo interactivamente desde PowerShell o alguna otra CLI, pero al mismo tiempo también encontrar una manera de instalar el mismo archivo EXE como un servicio de Windows y hacer que se ejecute sin supervisión .

¿Puedo hacer esto? Y si es así: ¿cómo puedo hacer esto?

¿Fue útil?

Solución

Sí, puedes.

Una forma de hacerlo sería usar un parámetro de línea de comando, digamos " / console " ;, para diferenciar la versión de consola de la versión de ejecución como servicio:

  • cree una aplicación de consola de Windows y luego
  • en Program.cs, más precisamente en la función Principal, puede probar la presencia de " / console " param
  • si la " / consola " está ahí, comienza el programa normalmente
  • si el parámetro no está allí, invoque su clase de servicio desde un ServiceBase


// Class that represents the Service version of your app
public class serviceSample : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        // Run the service version here 
        //  NOTE: If you're task is long running as is with most 
        //  services you should be invoking it on Worker Thread 
        //  !!! don't take too long in this function !!!
        base.OnStart(args);
    }
    protected override void OnStop()
    {
        // stop service code goes here
        base.OnStop();
    }
}

...

Luego en Program.cs:


static class Program
{
    // The main entry point for the application.
    static void Main(string[] args)
    {
        ServiceBase[] ServicesToRun;

    if ((args.Length > 0) && (args[0] == "/console"))
    {
        // Run the console version here
    }
    else
    {
        ServicesToRun = new ServiceBase[] { new serviceSample () };
        ServiceBase.Run(ServicesToRun);
    }
}

}

Otros consejos

La mejor manera de lograr esto desde un punto de vista de diseño es implementar toda su funcionalidad en un proyecto de biblioteca y crear proyectos envolventes separados a su alrededor para ejecutar la forma que desee (es decir, un servicio de Windows, un programa de línea de comandos, un ASP). servicio web neto, un servicio wcf etc.)

Sí, se puede hacer.

Su clase de inicio debe extender ServiceBase.

Puede usar su método de inicio Main estático vacío (string [] args) para analizar un interruptor de línea de comando para que se ejecute en modo consola.

Algo así como:

static void Main(string[] args)
{
   if ( args == "blah") 
   {
      MyService();
   } 
   else 
   {
      System.ServiceProcess.ServiceBase[] ServicesToRun;
      ServicesToRun = new System.ServiceProcess.ServiceBase[] { new MyService() };
      System.ServiceProcess.ServiceBase.Run(ServicesToRun);
   }

Un servicio de Windows es bastante diferente de un programa normal de Windows; es mejor que no intentes hacer dos cosas a la vez.

¿Ha considerado hacer una tarea programada en su lugar?

servicio de Windows vs tarea programada

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