Adding a Console via Program logic

2020-06-06 01:44发布

I have a windows service. If I start it from the debugger I want to run with console output (since you can not run a service).

Usually a Windows Service is set to WindowApplication as project type and has no "window" entry point. Thus it removes the good old console.

If you want a console window you need to change the project type to ConsoleAppication. I would like to do this within the program itself instead changing the Project settings.

Is it possible?

标签: c# service
5条回答
Juvenile、少年°
2楼-- · 2020-06-06 02:32

I usually develop any program as a class library (or set of libraries), with a logical entry point, then I add the launcher project wrapper: a console application, a windows service, a web site.

If, in your program, you have an entry point (a class with a method that starts all your business logic), then you can build it as a class library without any changes and add a console project and a windows service project to your solution that, in the main class (e.g. Program.cs) instantiates the entry point and call the entry method.

This approach does not invade your business logic with use approach and lets you build every mode of use every time you build the entire solution. In other words it allows you to separates concerns: the program and how to launch it.

查看更多
▲ chillily
3楼-- · 2020-06-06 02:37

A good practise is having two programs (i.e. two projects in Visual Studio producing executables, plus one or more projects for the shared application logic):

  1. One for a Windows Service variant of your software;
  2. Another one for a console variant of your software.

The advantage is you can choose freely whether to run the software as a service or in console mode. For example, when run in console mode, with frameworks like Log4Net you can configure logging output to the console which helps in diagnosing problems in production environments.

查看更多
地球回转人心会变
4楼-- · 2020-06-06 02:40

You can use the AllocConsole API

[DllImport("kernel32.dll")]
static extern bool AllocConsole();

Use FreeConsole to detach the console from your process:

[DllImport("kernel32.dll")]
static extern bool FreeConsole();
查看更多
疯言疯语
5楼-- · 2020-06-06 02:40

Yes you can do it on multiple ways. I use the following solution:

  1. Create a Console Application project. Name it Console.Service or something else.

  2. Go to your service class and create the following code:

    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
    }
    
  3. Add a existing item to the Console Application project by linking to the Service class from your service project. You do this by clicking on the arrow next to the add button (Add as Link).

You're done. Like I said there are multiple ways to go. Choose the one you feel most happy with.

查看更多
三岁会撩人
6楼-- · 2020-06-06 02:47

Actually you can use a simple check when the program starts to see if it is running as a service or not and then use the AllocConsole command to start the console. Here is the sample code.

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.
            }           
         }        
     }
 }
查看更多
登录 后发表回答