我们正在运行在Winforms C#(.net framework 4.0)中开发的客户端 - 服务器应用程序,它具有以下组件
我们正在研究将服务器(控制台应用程序)实现为Windows服务的可能性。
首先让我概述一下我们决定采用的方法
我们需要回答一个问题。这里的尝试是使这个问题尽可能客观,因此可以归类为一个真实的问题。
我们是否需要将服务器转换为dll项目?
或者我们可以在windows服务项目中提供服务器exe文件的引用吗?
我个人认为第二种选择是不可能的。但我想知道我是否遗漏了什么。
提前感谢
罗米
答案 0 :(得分:2)
您可以在服务项目中添加exe作为参考。无论如何,Exe只是一个装配。也许你必须将某些类设置为公共,但如果你创建一个dll也会发生同样的情况。 我通常使用另一种技巧。 我从服务项目开始,我将其更改为控制台应用程序:
属性 - >应用程序 - >输出类型:控制台应用程序
然后我在主要内容中写下这样的内容:
if (Environment.UserInteractive)
{
log.Info("Starting as a console...");
// call my service runner
}
else{
log.Info("Starting as a service...");
log.Info(this.ServiceDisplayName);
log.Info(this.ServiceDescription);
ServiceBase[] servicesToRun = new ServiceBase[]
{
new MyServiceImpl();
};
try
{
ServiceBase.Run(servicesToRun);
}
catch (Exception e)
{
log.Fatal("A fatal error occurred while running.", e);
throw;
}
}
使用此策略,我有一个exe,它在交互式运行时表现得像一个控制台,但可以安装在服务控制管理器中。 也许类似的重构可以帮助您的代码。
答案 1 :(得分:1)
控制台应用程序可以像DLL一样被引用,您可以使用它包含的公共类。
答案 2 :(得分:1)
最好转换dll项目中的服务器代码,然后将该dll的引用添加到windows服务项目中并在那里使用。
但是,很可能将可执行项目的引用用于.net。
中的另一个项目Walkthrough: Creating a Windows Service Application in the Component Designer
答案 3 :(得分:1)
基于.NET的Windows服务本身并不是那么特别。您可以为两者使用相同的基于控制台的应用程序项目。主要区别是:
Environment.UserInteractive
标记为False
。您可以使用它来根据程序的执行方式更改程序的行为。 (例如,登录到控制台而不是Windows事件日志。)ServiceBase.Run()
启动,必须包含service installer components,并且为installed using installutil
或"self-installed"。我要做的是在the boilerplate in the docs之后将服务器创建为服务项目:
class MyServer : ServiceBase
{
protected override void OnStart(string[] args)
{
// OnStart() MUST return, so spawn off a thread here
}
public void MyStart(string[] args)
{
OnStart(args);
}
}
您必须在项目属性中将项目类型更改为“控制台应用程序”。服务应用程序模板的默认设置是“Windows应用程序”,但您使用它似乎并不重要。除了你应该通过安装它,启动它,然后附加远程调试器来调试服务的部分。感谢Cthulhu,当你:
时,这是不必要的根据Environment.UserInteractive
public static void Main(string[] args)
{
if (Environment.UserInteractive)
{
new MyServer().Start(args);
}
else
{
ServiceBase.Run(new ServiceBase[] { new MyServer() });
}
}
通过这种方式,您可以获得能够在独立模式下运行的Windows服务,可以使用F5进行调试。