Domanda

Qual è il modo migliore in C # per configurare un'app di utilità che può essere eseguita dalla riga di comando e produrre un output (o scrivere su un file), ma che potrebbe essere eseguita anche come servizio Windows per fare il suo lavoro in background (ad es. monitoraggio di una directory o altro).

Vorrei scrivere il codice una volta ed essere in grado di chiamarlo in modo interattivo da PowerShell o da qualche altra CLI, ma allo stesso tempo trovo anche un modo per installare lo stesso file EXE di un servizio Windows e farlo funzionare incustodito .

Posso farlo? E se è così: come posso farlo?

È stato utile?

Soluzione

Sì, puoi.

Un modo per farlo sarebbe quello di utilizzare un parametro della riga di comando, ad esempio " / console " ;, per distinguere la versione della console oltre alla versione di esecuzione come servizio:

  • crea un'app console di Windows e quindi
  • in Program.cs, più precisamente nella funzione Main puoi verificare la presenza di " / console " param
  • se " / console " c'è, avvia normalmente il programma
  • se il parametro non è presente, invoca la tua classe di servizio da 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();
    }
}

...

Quindi in 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);
    }
}

}

Altri suggerimenti

Il modo migliore per ottenere questo risultato dal punto di vista del design è implementare tutte le funzionalità in un progetto di libreria e costruire progetti wrapper separati attorno ad esso per eseguire nel modo desiderato (ad esempio un servizio Windows, un programma da riga di comando, un asp. servizio web net, un servizio wcf ecc.)

Sì, può essere fatto.

La tua classe di avvio deve estendere ServiceBase.

È possibile utilizzare il metodo di avvio principale vuoto (string [] args) per analizzare un'opzione della riga di comando per l'esecuzione in modalità console.

Qualcosa del tipo:

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 servizio Windows è abbastanza diverso da un normale programma Windows; è meglio non provare a fare due cose contemporaneamente.

Hai preso in considerazione l'idea di renderlo un'attività pianificata?

servizio Windows vs attività pianificata

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top