我将从一个示例开始:Apache Web服务器(在Windows下)有一个很好的功能:它既可以作为独立应用程序运行(具有当前用户权限),也可以作为Windows安装和运行直接服务(作为本地系统帐户),使用相同的可执行文件。
为了使应用程序作为独立应用程序运行,它需要做的就是在某些公共类中使用静态公共Main()。
为了使应用程序可以作为服务进行安装和运行,它必须以某种方式实现ServiceBase和Installer类。但是,如果像这样的应用程序作为独立应用程序运行,它将显示消息框。
如何实现类似Apache的操作模式?我相信解决方案很简单,但我真的不知道从哪里开始。
以下代码用于调用服务。可以修改它以允许独立使用吗?
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
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。
答案 0 :(得分:10)
在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());
}
这只是一个给你一个想法的例子,可能有更简洁的方法来编写这段代码。
答案 1 :(得分:8)
经过一番挖掘后,我终于查看了.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();
// ...
}
}
答案 2 :(得分:3)
您应该在库中抽象出所有功能。它碰巧从Windows服务运行的事实应该无关紧要。实际上,如果你有一个名为ServiceFrontEnd的面向类,它有一个Start()和Stop() - Windows服务应用程序可以调用它,那么命令行应用程序,Windows应用程序或其他任何东西都可以。
你在这里描述的只是需要更多的抽象。 “服务”的功能不需要与Windows服务的运行方式紧密耦合。希望有所帮助
答案 3 :(得分:0)
在您的网站示例中,我非常有信心Apache应用程序是用C或C ++编写的。为此,您需要一个ServiceMain函数。如果像普通程序一样执行它,则会调用main。如果您指向服务控制管理器,则会调用ServiceMain。
关于C#,不能说我知道这一点。如果我必须在c#中编写服务,我想我会从这里开始 - http://msdn.microsoft.com/en-us/library/bb483064.aspx