通过程序逻辑添加控制台
我有一个Windows服务。 如果我从调试器启动它,我想用控制台输出运行(因为你无法运行服务)。
通常,Windows服务设置为WindowApplication作为项目类型,并且没有“窗口”入口点。 因此它删除了旧的控制台。
如果需要控制台窗口,则需要将项目类型更改为ConsoleAppication。 我想在程序本身中执行此操作,而不是更改项目设置。
可能吗?
实际上,您可以在程序开始查看它是否作为服务运行时使用简单检查,然后使用AllocConsole命令启动控制台。 这是示例代码。
namespace TestService { static class Program { [DllImport("kernel32.dll")] static extern bool AllocConsole(); /// /// The main entry point for the application. /// 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 }
-
通过链接到服务项目中的Service类,将现有项添加到Console Application项目。 您可以通过单击添加按钮(添加为链接)旁边的箭头来执行此操作。
你完成了。 就像我说的那样,有很多方法可以去。 选择你最满意的那个。