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

我想编写一次代码,并且能够从 PowerShell 或其他一些 CLI 以交互方式调用它,但同时也找到一种方法来安装相同的 EXE 文件作为 Windows 服务并让它在无人值守的情况下运行。

我可以这样做吗?如果是这样:我怎样才能做到这一点?

有帮助吗?

解决方案

是的你可以。

一种方法是使用命令行参数(例如“/console”)来区分控制台版本和作为服务运行的版本:

  • 创建一个 Windows 控制台应用程序,然后
  • 在 Program.cs 中,更准确地说,在 Main 函数中,您可以测试“/console”参数是否存在
  • 如果有“/console”,则正常启动程序
  • 如果参数不存在,则从 ServiceBase 调用您的 Service 类


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

}

其他提示

从设计角度来看,实现这一目标的最佳方法是在库项目中实现所有功能,并围绕它构建单独的包装器项目以执行您想要的方式(即Windows服务,命令行程序,asp。网络服务,wcf服务等。)

是的,可以做到。

您的启动类必须扩展ServiceBase。

您可以使用static 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);
   }

Windows服务与普通的Windows程序完全不同;你最好不要一次做两件事。

您是否考虑过将其作为预定任务?

Windows服务与计划任务

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top