Pergunta

O que é a melhor maneira em C # para criar um aplicativo utilitário que pode ser executado a partir da linha de comando e produzir alguma saída (ou escrever para um arquivo), mas que poderia ser executado como um serviço do Windows, bem como para fazer o seu trabalho em segundo plano (por exemplo, o monitoramento de um diretório, ou qualquer outro).

Eu gostaria de escrever o código uma vez e ser capaz de tanto chamá-lo de forma interativa a partir PowerShell ou algum outro CLI, mas ao mesmo tempo também encontrar uma maneira de instalar o mesmo arquivo EXE como um serviço Windows e executá-lo sem vigilância .

Posso fazer isso? E se assim: como eu posso fazer isso

Foi útil?

Solução

Sim, pode.

Uma maneira de fazer isso seria usar um parâmetro de linha de comando, diga "/ console", para dizer a versão do console para além do prazo, como uma versão do serviço:

  • criar um Windows Console App e, em seguida,
  • no Program, mais precisamente na função principal que você pode testar para a presença do "/ console" param
  • Se o "/ console" está lá, iniciar o programa normalmente
  • Se o parâmetro não está lá, chame sua classe de serviço a partir de um 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();
    }
}

...

Então, em 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);
    }
}

}

Outras dicas

A melhor maneira de conseguir isso do ponto de vista do projeto é implementar toda a sua funcionalidade em um projeto de biblioteca e construir projetos de mensagens publicitárias separadas em torno dele para executar a maneira que você quer (ou seja, serviço de uma janela, um programa de linha de comando, um asp. serviço de web net, um serviço WCF etc.)

Sim, pode ser feito.

Sua classe de inicialização deve estender ServiceBase.

Você pode usar o seu static void Main (string [] args) método de inicialização para analisar uma opção de linha de comando para executar no modo de console.

Algo 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);
   }

Um serviço do Windows é bastante diferente de um programa normal do Windows; você está melhor não tentar fazer duas coisas ao mesmo tempo.

Você já considerou tornando-se uma tarefa agendada em vez disso?

serviço do Windows vs tarefa agendada

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top