我有一个项目作为Windows服务部署到生产中。但是,对于本地开发目的,将其作为控制台应用程序运行会很有用。目前,我有一个名为ReportingHost
的类,它提供了我的核心功能,还有一个名为ReportingServiceHost的类,它继承自ServiceBase
并允许我将应用程序作为服务运行。还有一个程序类,其主要方法在我的ReportingServiceHost上调用ServiceBase.Run
。
我想我需要编写一个允许我在控制台中运行该功能的ReportingConsoleHost
类。然后我需要修改我的Main
以对命令行开关做出反应并选择其中一个。这些是我遇到麻烦的两个部分。
我查看了this并试图使用该代码,但我的应用程序立即退出,它没有显示控制台窗口,也没有在关闭前等待Enter。
部分问题在于我对这些事情的运作方式没有深刻的理解。一个分裂我的功能的权威模式,我运行该功能的两种不同方式,以及一个基于命令行参数选择其中一种方式的主方法,这是我希望实现的。
答案 0 :(得分:9)
我怀疑你的测试项目是配置为windows exe,而不是控制台exe。使用Windows exe Console.ReadLine
将立即返回。
要使控制台exe既可以作为服务也可以在命令行中运行,将其作为服务项目(在Visual Studio中)启动 - 并在Environment.UserInteractive
上添加一个检查 - 即。
static void Main() {
if(Environment.UserInteractive) {
// code that starts the listener and waits on ReadLine
} else {
// run the service code that the VS template injected
}
}
您当然也可以使用命令行开关。我在microsoft.public.dotnet.languages.csharp上有一个例子:
取决于开关
答案 1 :(得分:2)
我之前通过实现正常的Windows服务(通过从ServiceBase派生)来完成此操作,但是检查main方法以检查命令行参数。
如果args包含/console
,请启动控制台版本,否则启动服务。
这样的事情:
internal class MyService : ServiceBase
{
internal static void Main(string[] args)
{
if (args.Length == 0)
{
// run as a service....
ServiceBase[] servicesToRun = new ServiceBase[] {new MyService()};
Run(servicesToRun);
}
else
{
// run as a console application....
}
}
}
答案 2 :(得分:2)
我的建议?将所有服务逻辑放在单独的程序集中。 (类库或DLL。)然后创建一个项目作为服务,引用您的类库并将代码用作服务。创建第二个控制台项目,该项目也引用您的类库,但它将使其可用作控制台应用程序。 您最终会在解决方案中使用三个不同的项目,但它确实允许您将事物分开。实际上,这样就可以将您的服务扩展到其他几种形状。例如,您可以将第4个项目创建为Web服务,从而通过客户端系统上的Web浏览器调用您的服务。由于软件逻辑与使用逻辑分离,因此您可以对其进行大量控制。
请注意,服务可能比控制台应用程序具有更多限制。通常,默认情况下,服务没有网络访问权限,没有为其分配监视器以显示错误消息,并且通常使用有限的用户帐户或系统帐户运行。您的服务可能会作为控制台运行,但由于此原因而失败。
答案 3 :(得分:1)
上面已经有两个很好的答案 - 但我想我会发布一个Brian Noyes' Debuggable Self-Host Windows Service Project博客帖子的链接 - 它谈论的是WCF但应该适用于任何'Windows服务'。
最好的是示例代码 - 如果您无法弄清楚上述示例“适合”的位置,请抓住整个项目并查看其工作原理。谢谢Brian!