如何制作Windows服务应用程序,以便它也可以作为独立程序运行?

我将从一个示例开始:Apache Web服务器(在Windows下)有一个很好的function:它既可以作为独立应用程序运行(具有当前用户权限),也可以作为Windows服务直接安装和运行(作为本地系统帐户),使用相同的可执行文件

为了使应用程序作为独立应用程序运行,它需要做的就是在某些公共类中使用静态公共Main()。

为了使应用程序可以作为服务进行安装和运行,它必须以某种方式实现ServiceBase和Installer类。 但是,如果像这样的应用程序作为独立应用程序运行,它将显示消息框。

如何实现这种类似Apache的操作模式? 我相信解决方案很简单,但我真的不知道从哪里开始。

下面的代码片段用于调用服务。 可以修改它以允许独立使用吗?

static class Program { ///  /// The main entry point for the application. ///  static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new Service() // defined elsewhere as Service : ServiceBase }; ServiceBase.Run(ServicesToRun); } } 

我选择的语言是C#。

编辑:目前,我已将公共代码抽象为单独的程序集(让我们称之为Library.dll),我有两个可执行文件:Console.exe和Service.exe,它们分别是独立的和Windows服务应用程序,两者都只是手段调用Library.dll。

我的目标是将这两个可执行文件合并为一个,仍然会调用Library.dll。

在C#中,一种简单的方法是要求命令行参数将其作为服务运行。 如果参数不存在,则运行表单/控制台应用程序。 然后让您的安装程序在安装服务时在可执行文件路径中包含参数,所以它看起来像这样:

 C:\MyApp\MyApp.exe -service 

它看起来像这样:

 static void Main(string[] args) { foreach (string arg in args) { //Run as a service if our argument is there if (arg.ToLower() == "-service") { ServiceBase[] servicesToRun = new ServiceBase[] { new Service1() }; ServiceBase.Run(servicesToRun); return; } } //Run the main form if the argument isn't present, like when a user opens the app from Explorer. Application.Run(new Form1()); } 

这只是一个给你一个想法的例子,可能有更简洁的方法来编写这段代码。

经过一番挖掘,我终于查看了.NET hood(System.ServiceProcess.ServiceBase.Run方法),发现它检查了Environment.UserInteractive bool,以确保可执行文件不是以交互方式运行的。

对我有用的过度简化的解决方案:

 class Program { static void Main(string[] args) { if (!Environment.UserInteractive) { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { // Service.OnStart() creates instance of MainLib() // and then calls its MainLib.Start() method new Service() }; ServiceBase.Run(ServicesToRun); return; } // Run in a console window MainLib lib = new MainLib(); lib.Start(); // ... } } 

您应该在库中抽象出所有function。 它碰巧从Windows服务运行这一事实无关紧要。 实际上,如果你有一个名为ServiceFrontEnd的面向类,它有一个Start()和Stop() – Windows服务应用程序可以调用它,那么命令行应用程序,Windows应用程序或其他任何东西都可以。

你在这里描述的只是需要更多的抽象。 “服务”的function不需要与Windows服务的运行方式紧密耦合。 希望有所帮助

在您的站点示例中,我非常有信心Apache应用程序是用C或C ++编写的。 为此,您需要一个ServiceMain函数。 如果你像普通程序一样执行它,那么main会被调用。 如果将服务控制管理器指向它,则会调用ServiceMain。

关于C#,不能说我知道这一点。 如果我不得不在c#中编写服务,我想我会从这里开始 – http://msdn.microsoft.com/en-us/library/bb483064.aspx