我有一个windows服务。如果我从调试器启动它,我希望使用控制台输出运行它(因为您不能运行服务)。
通常,Windows服务被设置为WindowApplication作为项目类型,并且没有"窗口"入口点。因此,它删除了好的旧控制台。
如果您想要一个控制台窗口,您需要将项目类型更改为ConsoleAppication。我想在程序本身中执行此操作,而不是更改项目设置。
有可能吗?
实际上,当程序开始运行时,您可以使用一个简单的检查来查看它是否作为服务运行,然后使用AllocConsole命令来启动控制台。这是示例代码。
namespace TestService
{
static class Program
{
[DllImport("kernel32.dll")]
static extern bool AllocConsole();
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
if (!Environment.UserInteractive)
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
else
{
AllocConsole();
//Start Code that interfaces with console.
}
}
}
}
您可以使用AllocConsole
API
[DllImport("kernel32.dll")]
static extern bool AllocConsole();
使用FreeConsole
将控制台与进程分离:
[DllImport("kernel32.dll")]
static extern bool FreeConsole();
我通常将任何程序开发为带有逻辑入口点的类库(或库集),然后添加启动器项目包装器:控制台应用程序、windows服务、网站。
如果在您的程序中,您有一个入口点(一个具有启动所有业务逻辑的方法的类),那么您可以在不做任何更改的情况下将其构建为类库,并向您的解决方案中添加一个控制台项目和一个windows服务项目,该项目在主类(例如program.cs)中实例化入口点并调用入口方法。
这种方法不会通过使用方法侵入您的业务逻辑,并允许您在每次构建整个解决方案时构建每种使用模式。换句话说,它允许您分离关注点:程序和如何启动它。
一个好的做法是拥有两个程序(即,Visual Studio中的两个项目生成可执行文件,再加上一个或多个用于共享应用程序逻辑的项目):
- 一个用于您的软件的Windows服务变体
- 另一个用于您的软件的控制台变体
优点是您可以自由选择是将软件作为服务运行还是在控制台模式下运行。例如,当在控制台模式下运行时,使用Log4Net等框架,您可以将日志输出配置到控制台,这有助于诊断生产环境中的问题。
是的,您可以通过多种方式实现。我使用以下解决方案:
-
创建控制台应用程序项目。将其命名为Console.Service或其他名称。
-
转到您的服务类并创建以下代码:
private static void Main() { #if !DEBUG var servicesToRun = new [] { new DemoService() }; Debug.WriteLine("Run service..."); Run(servicesToRun); #else DemoService service = new DemoService(); service.OnStart(null); Console.WriteLine("Press ENTER to quit..."); Console.ReadLine(); service.OnStop(); #endif }
-
通过从服务项目链接到服务类,将现有项添加到控制台应用程序项目。您可以通过单击添加按钮(添加为链接)旁边的箭头来执行此操作。
你完了。就像我说的,还有很多路要走。选择一个你觉得最幸福的人。