Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建组合命令行/Windows服务应用程序_C#_.net_Command Line_Windows Services - Fatal编程技术网

C# 创建组合命令行/Windows服务应用程序

C# 创建组合命令行/Windows服务应用程序,c#,.net,command-line,windows-services,C#,.net,Command Line,Windows Services,在C#中,设置实用程序应用程序的最佳方式是什么?该应用程序可以从命令行运行并生成一些输出(或写入文件),但也可以作为Windows服务运行,以便在后台执行其工作(例如,监视目录或其他) 我希望只编写一次代码,并且能够从PowerShell或其他CLI交互调用它,但同时也可以找到一种方法,将相同的EXE文件安装为Windows服务,并让它在无人参与的情况下运行 我能做这个吗?如果是这样的话:我该怎么做呢?是的,你可以 一种方法是使用命令行参数,比如“/console”,将控制台版本与运行方式服务版

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

我希望只编写一次代码,并且能够从PowerShell或其他CLI交互调用它,但同时也可以找到一种方法,将相同的EXE文件安装为Windows服务,并让它在无人参与的情况下运行

我能做这个吗?如果是这样的话:我该怎么做呢?

是的,你可以

一种方法是使用命令行参数,比如“/console”,将控制台版本与运行方式服务版本区分开来:

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

Windows服务与普通Windows程序大不相同;你最好不要同时做两件事

你有没有考虑过把它变成一项预定的任务

是的,可以做到

您的启动类必须扩展ServiceBase

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

比如:


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

我也一直在考虑这一点,是的,但我有一个web应用程序,一堆SQL作业,一堆Windows服务,一堆命令行工具,现在还有一堆被用作计划任务的工具。。。。实际上,我正在努力减少我需要照顾和管理的不同类型的事情的数量。无论如何,谢谢你的投入!我已经成功创建了可以从命令行运行的应用程序,并且也可以作为windows服务安装和运行,但我同意@Mark Ransom的观点,至少他们是非常不同的野兽,并且您必须小心实现,尤其是在使用服务时。正如我在示例的代码注释中提到的,不要从OnStart事件处理程序运行任何阻塞任务。相反,在单独的线程或类似的异步构造上启动服务!您可以检查Environment.UserInteractive以查看我们是否处于交互模式,而不是args check。

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

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