第一次手动启动后,永远自动运行Windows服务

时间:2016-05-16 08:16:59

标签: c# windows-services

我创建了一个Windows服务应用程序。它的运行取决于app.config文件中包含的应用程序设置。它将同时安装在不同的位置(网络,PC)。每个位置都需要在app.config文件中设置自己的参数。所以我不希望它在安装后自动运行。通过这样做,每个位置用户将能够打开配置文件并进行更改。然后他们就可以开始服务。但之后服务将永远运行。即使他们重新启动Windows,它也会在Windows打开后自动运行。

这是我的安装程序类。安装后它不会自动运行。这很好。但如果我手动运行并重新启动PC,重启完成后,仍然需要手动启动。我该怎么办?

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);
            }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

您可以通过下载名为TopShelf的NuGet包来使自己更轻松。

简要总结一下,引用他们的page

  

Topshelf是托管使用.NET编写的服务的框架   框架。简化了服务的创建,允许开发人员   创建一个可以作为安装的简单控制台应用程序   使用Topshelf的服务。原因很简单:它很远   比服务更容易调试控制台应用程序。而且一旦   应用程序经过测试并可以投入生产,Topshelf使其变得简单   将应用程序安装为服务。

答案 1 :(得分:0)

您可以在服务启动后使用sc config来修改启动类型。

例如。

sc config yourservicename start=auto

或者您可以使用ChangeServiceConfig

答案 2 :(得分:0)

您的代码似乎已将启动类型设置为“自动”。

您是否可以检查事件日志以查看您的服务是否尝试自动启动,但是失败了。如果您的服务依赖于尚未启动的其他服务,则会发生这种情况。