创建一个组合命令行/Windows服务应用程序

14

在C#中设置一个实用程序应用程序的最佳方法是什么?该应用程序可以从命令行运行并生成一些输出(或写入文件),但也可以作为Windows服务运行以在后台完成其作业(例如,监视目录或其他操作)。

我想编写一次代码,既可以从PowerShell或其他CLI交互式调用它,同时也可以找到一种方法将同一EXE文件安装为Windows服务并使其无人值守运行。

我能做到这点吗?如果可以:如何做到这一点?

4个回答

21

是的,您可以这样做。

一种方法是使用命令行参数,比如 "/console",来区分控制台版本和作为服务运行的版本:

  • 创建一个Windows控制台应用程序
  • 在Program.cs文件中,在Main函数中可以测试是否存在 "/console" 参数
  • 如果存在 "/console",则正常启动程序
  • 如果不存在该参数,则从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();
    }
}

然后在 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);
    }
}

}


4
不需要使用 args 检查,可以检查 Environment.UserInteractive 来判断是否处于交互模式。 - nzeemin

4

从设计的角度来看,实现所有功能的最佳方式是在库项目中实现,并构建单独的包装器项目以按您想要的方式执行(例如:Windows服务、命令行程序、ASP.NET Web服务、WCF服务等)。


3

可以做到。

您的启动类必须扩展ServiceBase。

您可以使用静态void Main(string [] args)启动方法来解析命令行开关以在控制台模式下运行。

类似以下内容:

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

1

我也一直在考虑这个问题,但是我有一个Web应用程序、一堆SQL作业、一堆Windows服务、一堆命令行工具,现在还有一堆被用作计划任务的东西……我实际上正在尝试减少需要照顾和管理的不同类型的事物数量。无论如何,感谢您的建议! - marc_s
我已经成功创建了可以从命令行运行的应用程序,并安装和运行为Windows服务,但我同意@Mark Ransom的观点,至少它们是非常不同的东西,并且您必须小心实施 - 特别是服务方面。正如我在示例中的代码注释中提到的那样,不要从OnStart事件处理程序运行任何阻塞任务。相反,请在单独的线程或某些类似的异步构造上启动服务! - Mike Dinescu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接