14

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

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

我可以这样做吗?如果是这样:我该怎么做?

4个答案4

重置为默认值
21

是的,你可以。

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

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

//表示应用程序的服务版本的类公共类服务示例:ServiceBase{protected override void OnStart(字符串[]参数){//在此处运行服务版本//注意:如果您的任务与大多数任务一样长时间运行//应该在工作线程上调用它的服务//  !!! 不要在这个函数中花费太长时间!!!底座。OnStart(参数);}受保护的覆盖void OnStop(){//此处显示停止服务代码底座。OnStop();}}

...

然后在Program.cs中:

静态类程序{//应用程序的主要入口点。static void Main(字符串[]参数){ServiceBase[]要运行的服务;

if((args.Length>0)&&(args[0]=“/console”){//在此处运行控制台版本}其他的{ServicesToRun=新ServiceBase[]{新serviceSample()};服务库。运行(ServicesToRun);}}

}

1
  • 4
    您可以选中Environment而不是args检查。UserInteractive查看是否处于交互模式。 评论 2016年1月13日8:20
4

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

0

是的,这是可以做到的。

您的启动类必须扩展ServiceBase。

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

类似于:

static void Main(字符串[]参数){如果(args==“blah”){我的服务();} 其他{系统。服务流程。ServiceBase[]要运行的服务;ServicesToRun=新系统。服务流程。ServiceBase[]{new MyService()};系统。服务流程。服务库。运行(ServicesToRun);}
1

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

你考虑过把它变成一项计划任务吗?

windows服务与计划任务

2
  • 我也一直在考虑这个问题,是的,但我有一个web应用程序,一堆SQL作业,一堆Windows服务,一堆命令行工具,现在还有一堆被用作计划任务的工具。。。。实际上,我正在尝试减少我需要处理和管理的不同类型的事情的数量。无论如何,感谢您的输入!
    – 马克
    评论 2009年4月30日21:24
  • 我已经成功地创建了可以从命令行运行的应用程序,也可以作为windows服务安装和运行,但我同意@Mark Ransom的观点,至少他们是非常不同的动物,你必须小心实现,尤其是服务。就像我在示例中的代码注释中提到的那样,不要从OnStart事件处理程序运行任何阻塞任务。相反,在单独的线程或类似的异步构造上启动服务! 评论 2009年4月30日21:35

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览已标记的其他问题问你自己的问题.