How to make windows service application so it can run as a standalone program as well?

心已入冬 提交于 2019-12-02 20:46:58

In C#, an easy way to do it is to require a command line argument to run it as a service. If the argument isn't there, then run your form/console app. Then just have your installer include the argument in the executable path when installing the service so it looks like so:

C:\MyApp\MyApp.exe -service

It would look something like this:

static void Main(string[] args)
{
    foreach (string arg in args)
    {
        //Run as a service if our argument is there
        if (arg.ToLower() == "-service")
        {
            ServiceBase[] servicesToRun = new ServiceBase[] { new Service1() };
            ServiceBase.Run(servicesToRun);
            return;
        }
    }

    //Run the main form if the argument isn't present, like when a user opens the app from Explorer.
    Application.Run(new Form1());
}

This is just an example to give you an idea, there are probably cleaner ways to write this code.

After some digging, I have finally looked under .NET hood (System.ServiceProcess.ServiceBase.Run method), only to find that it checks Environment.UserInteractive bool to make sure that executable is NOT run interactively.

Oversimplified solution that works for me:

class Program
{
    static void Main(string[] args)
    {
        if (!Environment.UserInteractive)
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                // Service.OnStart() creates instance of MainLib() 
                // and then calls its MainLib.Start() method
                new Service()
            };
            ServiceBase.Run(ServicesToRun);
            return;
        }

        // Run in a console window
        MainLib lib = new MainLib();
        lib.Start();
        // ...
    }
}

You should really have all of your functionality abstracted in a library. The fact that it happens to be run from a Windows Service should not matter. In fact, if you had a faced class called ServiceFrontEnd that had a Start() and Stop() - the Windows Service application could call that, and so could a command-line app, a windows app, or whatever.

What you're describing here just needs more abstraction. The functionality of "the service" doesn't need to be tightly-coupled to how a Windows Service happens to operate. hope that helps

In the example you site, I'm pretty confident the Apache app is written in C or C++. For that, you would need a ServiceMain function. If you execute it like a normal program, main gets called. If you point the service control manager at it, ServiceMain gets called instead.

Regarding C#, can't say I know about that. If I had to write a service in c#, I suppose I would start here - http://msdn.microsoft.com/en-us/library/bb483064.aspx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!