简体   繁体   中英

Run windows service automatically forever, after starting manually for the first time

I created a Windows service application. It runs depending on the app settings which is included in the app.config file. It will be installed on different locations (networks, PCs) at the same time. Each location will need to set its own parameters in the app.config file. So I don't want it to run automatically after installation. By doing that each location users will be able to open configuration file and change it. Then they can start the service. But after that the service will run forever. Even when they restart the windows, it will run automatically after Windows opened.

Here is my installer class. It doesn't run automatically after installation. That's good. But if I run it manually and restart PC, when restart complete, it still waits to be started manually. What should I do?

public partial class MyServiceInstaller : System.Configuration.Install.Installer
{
    ServiceInstaller _serviceInstaller = new ServiceInstaller();
    ServiceProcessInstaller _processInstaller = new ServiceProcessInstaller();
    string _serviceName = "MyService";
    string _displayName = "My Service";
    string _description = "My Service - Windows Service";

    public MyServiceInstaller()
    {
        InitializeComponent();

        this.BeforeInstall += new InstallEventHandler(MyServiceInstaller_BeforeInstall);

        _processInstaller.Account = ServiceAccount.LocalSystem;

        _serviceInstaller.StartType = ServiceStartMode.Automatic;
        _serviceInstaller.Description = _description;
        _serviceInstaller.ServiceName = _serviceName;
        _serviceInstaller.DisplayName = _displayName;

        Installers.Add(_serviceInstaller);
        Installers.Add(_processInstaller);
    }

    protected override void OnCommitted(System.Collections.IDictionary savedState)
    {
        ServiceController sc = new ServiceController(_serviceName);

        if (sc.Status != ServiceControllerStatus.Running)
        {
            TimeSpan timeout = TimeSpan.FromMilliseconds(10000);
            sc.Start();
            sc.WaitForStatus(ServiceControllerStatus.Running, timeout);
            sc.Stop();
        }
        else
        {
            RestartService(10000);
        }
    }

    private void RestartService(int timeoutMiliseconds)
    {
        ServiceController service = new ServiceController(_serviceName);

        int millisec1 = Environment.TickCount;
        TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMiliseconds);

        service.Stop();
        service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);

        int millisec2 = Environment.TickCount;
        timeout = TimeSpan.FromMilliseconds(timeoutMiliseconds - (millisec2 - millisec1));

        service.Start();
        service.WaitForStatus(ServiceControllerStatus.Running, timeout);
    }

    void MyServiceInstaller_BeforeInstall(object sender, System.Configuration.Install.InstallEventArgs e)
    {
        List<ServiceController> services = new List<ServiceController>(ServiceController.GetServices());

        foreach (ServiceController s in services)
        {
            if (s.ServiceName == this._serviceInstaller.ServiceName)
            {
                ServiceInstaller ServiceInstallerObj = new ServiceInstaller();
                ServiceInstallerObj.Context = new System.Configuration.Install.InstallContext();
                ServiceInstallerObj.Context = Context;
                ServiceInstallerObj.ServiceName = _serviceName;
                ServiceInstallerObj.Uninstall(null);
            }
        }
    }
}

You can make this easier for yourself, by downloading the NuGet Package called TopShelf .

To summarize briefly, quoting from their page :

Topshelf is a framework for hosting services written using the .NET framework. The creation of services is simplified, allowing developers to create a simple console application that can be installed as a service using Topshelf. The reason for this is simple: It is far easier to debug a console application than a service. And once the application is tested and ready for production, Topshelf makes it easy to install the application as a service.

You can use sc config after service start to modify start type.

eg.

sc config yourservicename start=auto

Or you can use ChangeServiceConfig .

Your code already seems to be setting the startup type to Automatic.

Can you check the event log to see if your service is attempting to start automatically, but failing. This can happen if your service depends on another service which has not yet started.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM