如何在安装后立即启动。net Windows服务?

时间:2022-01-23 22:56:47

Besides the service.StartType = ServiceStartMode.Automatic my service does not start after installation

除了服务。StartType = ServiceStartMode。自动我的服务在安装后不会启动

Solution

解决方案

Inserted this code on my ProjectInstaller

在我的项目安装程序中插入此代码。

protected override void OnAfterInstall(System.Collections.IDictionary savedState)
{
    base.OnAfterInstall(savedState);
    using (var serviceController = new ServiceController(this.serviceInstaller1.ServiceName, Environment.MachineName))
        serviceController.Start();
}

Thanks to ScottTx and Francis B.

感谢ScottTx和Francis B。

8 个解决方案

#1


21  

You can do this all from within your service executable in response to events fired from the InstallUtil process. Override the OnAfterInstall event to use a ServiceController class to start the service.

您可以在服务可执行文件中执行所有这些操作,以响应从InstallUtil进程触发的事件。覆盖OnAfterInstall事件以使用ServiceController类来启动服务。

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

#2


159  

I've posted a step-by-step procedure for creating a Windows service in C# here. It sounds like you're at least to this point, and now you're wondering how to start the service once it is installed. Setting the StartType property to Automatic will cause the service to start automatically after rebooting your system, but it will not (as you've discovered) automatically start your service after installation.

我在这里发布了一个用c#创建Windows服务的步骤。听起来您至少达到了这一点,现在您想知道如何在安装后启动服务。将StartType属性设置为Automatic将导致服务在重新启动系统后自动启动,但它不会(如您所发现的)在安装后自动启动服务。

I don't remember where I found it originally (perhaps Marc Gravell?), but I did find a solution online that allows you to install and start your service by actually running your service itself. Here's the step-by-step:

我不记得最初是在哪里找到的(也许是Marc Gravell?),但我确实在网上找到了一个解决方案,让您可以通过实际运行服务本身来安装和启动服务。这里有一个循序渐进的:

  1. Structure the Main() function of your service like this:

    将您的服务的主()函数结构如下:

    static void Main(string[] args)
    {
        if (args.Length == 0) {
            // Run your service normally.
            ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()};
            ServiceBase.Run(ServicesToRun);
        } else if (args.Length == 1) {
            switch (args[0]) {
                case "-install":
                    InstallService();
                    StartService();
                    break;
                case "-uninstall":
                    StopService();
                    UninstallService();
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
    }
    
  2. Here is the supporting code:

    以下是支持代码:

    using System.Collections;
    using System.Configuration.Install;
    using System.ServiceProcess;
    
    private static bool IsInstalled()
    {
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                ServiceControllerStatus status = controller.Status;
            } catch {
                return false;
            }
            return true;
        }
    }
    
    private static bool IsRunning()
    {
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            if (!IsInstalled()) return false;
            return (controller.Status == ServiceControllerStatus.Running);
        }
    }
    
    private static AssemblyInstaller GetInstaller()
    {
        AssemblyInstaller installer = new AssemblyInstaller(
            typeof(YourServiceType).Assembly, null);
        installer.UseNewContext = true;
        return installer;
    }
    
  3. Continuing with the supporting code...

    继续支持代码…

    private static void InstallService()
    {
        if (IsInstalled()) return;
    
        try {
            using (AssemblyInstaller installer = GetInstaller()) {
                IDictionary state = new Hashtable();
                try {
                    installer.Install(state);
                    installer.Commit(state);
                } catch {
                    try {
                        installer.Rollback(state);
                    } catch { }
                    throw;
                }
            }
        } catch {
            throw;
        }
    }
    
    private static void UninstallService()
    {
        if ( !IsInstalled() ) return;
        try {
            using ( AssemblyInstaller installer = GetInstaller() ) {
                IDictionary state = new Hashtable();
                try {
                    installer.Uninstall( state );
                } catch {
                    throw;
                }
            }
        } catch {
            throw;
        }
    }
    
    private static void StartService()
    {
        if ( !IsInstalled() ) return;
    
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                if ( controller.Status != ServiceControllerStatus.Running ) {
                    controller.Start();
                    controller.WaitForStatus( ServiceControllerStatus.Running, 
                        TimeSpan.FromSeconds( 10 ) );
                }
            } catch {
                throw;
            }
        }
    }
    
    private static void StopService()
    {
        if ( !IsInstalled() ) return;
        using ( ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                if ( controller.Status != ServiceControllerStatus.Stopped ) {
                    controller.Stop();
                    controller.WaitForStatus( ServiceControllerStatus.Stopped, 
                         TimeSpan.FromSeconds( 10 ) );
                }
            } catch {
                throw;
            }
        }
    }
    
  4. At this point, after you install your service on the target machine, just run your service from the command line (like any ordinary application) with the -install command line argument to install and start your service.

    此时,在目标机器上安装服务之后,只需从命令行(与任何普通应用程序一样)运行服务,并使用-install命令行参数安装和启动服务。

I think I've covered everything, but if you find this doesn't work, please let me know so I can update the answer.

我想我已经涵盖了所有内容,但如果你发现这行不通,请告诉我以便我可以更新答案。

#3


7  

Visual Studio

Visual Studio

If you are creating a setup project with VS, you can create a custom action who called a .NET method to start the service. But, it is not really recommended to use managed custom action in a MSI. See this page.

如果您正在使用VS创建一个安装项目,您可以创建一个自定义操作,该操作调用. net方法来启动服务。但是,不建议在MSI中使用托管自定义操作。看到这个页面。

ServiceController controller  = new ServiceController();
controller.MachineName = "";//The machine where the service is installed;
controller.ServiceName = "";//The name of your service installed in Windows Services;
controller.Start();

InstallShield or Wise

一种软件产品或明智的

If you are using InstallShield or Wise, these applications provide the option to start the service. Per example with Wise, you have to add a service control action. In this action, you specify if you want to start or stop the service.

如果您正在使用InstallShield或者Wise,这些应用程序提供了启动服务的选项。每个示例中,您必须添加一个服务控制操作。在此操作中,指定要启动或停止服务。

Wix

Using Wix you need to add the following xml code under the component of your service. For more information about that, you can check this page.

使用Wix,您需要在服务的组件下添加以下xml代码。有关这方面的更多信息,请参阅本页。

<ServiceInstall 
    Id="ServiceInstaller"  
    Type="ownProcess"  
    Vital="yes"  
    Name=""  
    DisplayName=""  
    Description=""  
    Start="auto"  
    Account="LocalSystem"   
    ErrorControl="ignore"   
    Interactive="no">  
        <ServiceDependency Id="????"/> ///Add any dependancy to your service  
</ServiceInstall>

#4


6  

You need to add a Custom Action to the end of the 'ExecuteImmediate' sequence in the MSI, using the component name of the EXE or a batch (sc start) as the source. I don't think this can be done with Visual Studio, you may have to use a real MSI authoring tool for that.

您需要在MSI中的“ExecuteImmediate”序列末尾添加一个自定义操作,使用EXE或批处理(sc start)的组件名作为源。我不认为这可以用Visual Studio完成,您可能需要使用一个真正的MSI创作工具。

#5


5  

To start it right after installation, I generate a batch file with installutil followed by sc start

要在安装后立即启动它,我使用installutil和sc start生成一个批处理文件

It's not ideal, but it works....

这是不理想的,但它的工作原理....

#6


5  

Use the .NET ServiceController class to start it, or issue the commandline command to start it --- "net start servicename". Either way works.

使用. net ServiceController类来启动它,或者发出命令行命令来启动它——“net start servicename”。无论哪种方式。

#7


5  

To add to ScottTx's answer, here's the actual code to start the service if you're doing it the Microsoft way (ie. using a Setup project etc...)

要补充ScottTx的答案,这里有启动服务的实际代码,如果您使用微软的方式(即)。使用安装项目等)

(excuse the VB.net code, but this is what I'm stuck with)

(请原谅VB.net代码,但这正是我所需要的)

Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall
    Dim sc As New ServiceController()
    sc.ServiceName = ServiceInstaller1.ServiceName

    If sc.Status = ServiceControllerStatus.Stopped Then
        Try
            ' Start the service, and wait until its status is "Running".
            sc.Start()
            sc.WaitForStatus(ServiceControllerStatus.Running)

            ' TODO: log status of service here: sc.Status
        Catch ex As Exception
            ' TODO: log an error here: "Could not start service: ex.Message"
            Throw
        End Try
    End If
End Sub

To create the above event handler, go to the ProjectInstaller designer where the 2 controlls are. Click on the ServiceInstaller1 control. Go to the properties window under events and there you'll find the AfterInstall event.

要创建上述事件处理程序,请转到ProjectInstaller设计器,其中有两个控件。单击ServiceInstaller1控件。转到“事件”下的“属性”窗口,您将在那里找到AfterInstall事件。

Note: Don't put the above code under the AfterInstall event for ServiceProcessInstaller1. It won't work, coming from experience. :)

注意:不要将上述代码放在ServiceProcessInstaller1的AfterInstall事件中。从经验来看,这是行不通的。:)

#8


-1  

The easiest solution is found here install-windows-service-without-installutil-exe by @Hoàng Long

最简单的解决方案是@Hoang Long的install-windows-service- withoutinstallutil -exe

@echo OFF
echo Stopping old service version...
net stop "[YOUR SERVICE NAME]"
echo Uninstalling old service version...
sc delete "[YOUR SERVICE NAME]"

echo Installing service...
rem DO NOT remove the space after "binpath="!
sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto
echo Starting server complete
pause

#1


21  

You can do this all from within your service executable in response to events fired from the InstallUtil process. Override the OnAfterInstall event to use a ServiceController class to start the service.

您可以在服务可执行文件中执行所有这些操作,以响应从InstallUtil进程触发的事件。覆盖OnAfterInstall事件以使用ServiceController类来启动服务。

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

#2


159  

I've posted a step-by-step procedure for creating a Windows service in C# here. It sounds like you're at least to this point, and now you're wondering how to start the service once it is installed. Setting the StartType property to Automatic will cause the service to start automatically after rebooting your system, but it will not (as you've discovered) automatically start your service after installation.

我在这里发布了一个用c#创建Windows服务的步骤。听起来您至少达到了这一点,现在您想知道如何在安装后启动服务。将StartType属性设置为Automatic将导致服务在重新启动系统后自动启动,但它不会(如您所发现的)在安装后自动启动服务。

I don't remember where I found it originally (perhaps Marc Gravell?), but I did find a solution online that allows you to install and start your service by actually running your service itself. Here's the step-by-step:

我不记得最初是在哪里找到的(也许是Marc Gravell?),但我确实在网上找到了一个解决方案,让您可以通过实际运行服务本身来安装和启动服务。这里有一个循序渐进的:

  1. Structure the Main() function of your service like this:

    将您的服务的主()函数结构如下:

    static void Main(string[] args)
    {
        if (args.Length == 0) {
            // Run your service normally.
            ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()};
            ServiceBase.Run(ServicesToRun);
        } else if (args.Length == 1) {
            switch (args[0]) {
                case "-install":
                    InstallService();
                    StartService();
                    break;
                case "-uninstall":
                    StopService();
                    UninstallService();
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
    }
    
  2. Here is the supporting code:

    以下是支持代码:

    using System.Collections;
    using System.Configuration.Install;
    using System.ServiceProcess;
    
    private static bool IsInstalled()
    {
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                ServiceControllerStatus status = controller.Status;
            } catch {
                return false;
            }
            return true;
        }
    }
    
    private static bool IsRunning()
    {
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            if (!IsInstalled()) return false;
            return (controller.Status == ServiceControllerStatus.Running);
        }
    }
    
    private static AssemblyInstaller GetInstaller()
    {
        AssemblyInstaller installer = new AssemblyInstaller(
            typeof(YourServiceType).Assembly, null);
        installer.UseNewContext = true;
        return installer;
    }
    
  3. Continuing with the supporting code...

    继续支持代码…

    private static void InstallService()
    {
        if (IsInstalled()) return;
    
        try {
            using (AssemblyInstaller installer = GetInstaller()) {
                IDictionary state = new Hashtable();
                try {
                    installer.Install(state);
                    installer.Commit(state);
                } catch {
                    try {
                        installer.Rollback(state);
                    } catch { }
                    throw;
                }
            }
        } catch {
            throw;
        }
    }
    
    private static void UninstallService()
    {
        if ( !IsInstalled() ) return;
        try {
            using ( AssemblyInstaller installer = GetInstaller() ) {
                IDictionary state = new Hashtable();
                try {
                    installer.Uninstall( state );
                } catch {
                    throw;
                }
            }
        } catch {
            throw;
        }
    }
    
    private static void StartService()
    {
        if ( !IsInstalled() ) return;
    
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                if ( controller.Status != ServiceControllerStatus.Running ) {
                    controller.Start();
                    controller.WaitForStatus( ServiceControllerStatus.Running, 
                        TimeSpan.FromSeconds( 10 ) );
                }
            } catch {
                throw;
            }
        }
    }
    
    private static void StopService()
    {
        if ( !IsInstalled() ) return;
        using ( ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                if ( controller.Status != ServiceControllerStatus.Stopped ) {
                    controller.Stop();
                    controller.WaitForStatus( ServiceControllerStatus.Stopped, 
                         TimeSpan.FromSeconds( 10 ) );
                }
            } catch {
                throw;
            }
        }
    }
    
  4. At this point, after you install your service on the target machine, just run your service from the command line (like any ordinary application) with the -install command line argument to install and start your service.

    此时,在目标机器上安装服务之后,只需从命令行(与任何普通应用程序一样)运行服务,并使用-install命令行参数安装和启动服务。

I think I've covered everything, but if you find this doesn't work, please let me know so I can update the answer.

我想我已经涵盖了所有内容,但如果你发现这行不通,请告诉我以便我可以更新答案。

#3


7  

Visual Studio

Visual Studio

If you are creating a setup project with VS, you can create a custom action who called a .NET method to start the service. But, it is not really recommended to use managed custom action in a MSI. See this page.

如果您正在使用VS创建一个安装项目,您可以创建一个自定义操作,该操作调用. net方法来启动服务。但是,不建议在MSI中使用托管自定义操作。看到这个页面。

ServiceController controller  = new ServiceController();
controller.MachineName = "";//The machine where the service is installed;
controller.ServiceName = "";//The name of your service installed in Windows Services;
controller.Start();

InstallShield or Wise

一种软件产品或明智的

If you are using InstallShield or Wise, these applications provide the option to start the service. Per example with Wise, you have to add a service control action. In this action, you specify if you want to start or stop the service.

如果您正在使用InstallShield或者Wise,这些应用程序提供了启动服务的选项。每个示例中,您必须添加一个服务控制操作。在此操作中,指定要启动或停止服务。

Wix

Using Wix you need to add the following xml code under the component of your service. For more information about that, you can check this page.

使用Wix,您需要在服务的组件下添加以下xml代码。有关这方面的更多信息,请参阅本页。

<ServiceInstall 
    Id="ServiceInstaller"  
    Type="ownProcess"  
    Vital="yes"  
    Name=""  
    DisplayName=""  
    Description=""  
    Start="auto"  
    Account="LocalSystem"   
    ErrorControl="ignore"   
    Interactive="no">  
        <ServiceDependency Id="????"/> ///Add any dependancy to your service  
</ServiceInstall>

#4


6  

You need to add a Custom Action to the end of the 'ExecuteImmediate' sequence in the MSI, using the component name of the EXE or a batch (sc start) as the source. I don't think this can be done with Visual Studio, you may have to use a real MSI authoring tool for that.

您需要在MSI中的“ExecuteImmediate”序列末尾添加一个自定义操作,使用EXE或批处理(sc start)的组件名作为源。我不认为这可以用Visual Studio完成,您可能需要使用一个真正的MSI创作工具。

#5


5  

To start it right after installation, I generate a batch file with installutil followed by sc start

要在安装后立即启动它,我使用installutil和sc start生成一个批处理文件

It's not ideal, but it works....

这是不理想的,但它的工作原理....

#6


5  

Use the .NET ServiceController class to start it, or issue the commandline command to start it --- "net start servicename". Either way works.

使用. net ServiceController类来启动它,或者发出命令行命令来启动它——“net start servicename”。无论哪种方式。

#7


5  

To add to ScottTx's answer, here's the actual code to start the service if you're doing it the Microsoft way (ie. using a Setup project etc...)

要补充ScottTx的答案,这里有启动服务的实际代码,如果您使用微软的方式(即)。使用安装项目等)

(excuse the VB.net code, but this is what I'm stuck with)

(请原谅VB.net代码,但这正是我所需要的)

Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall
    Dim sc As New ServiceController()
    sc.ServiceName = ServiceInstaller1.ServiceName

    If sc.Status = ServiceControllerStatus.Stopped Then
        Try
            ' Start the service, and wait until its status is "Running".
            sc.Start()
            sc.WaitForStatus(ServiceControllerStatus.Running)

            ' TODO: log status of service here: sc.Status
        Catch ex As Exception
            ' TODO: log an error here: "Could not start service: ex.Message"
            Throw
        End Try
    End If
End Sub

To create the above event handler, go to the ProjectInstaller designer where the 2 controlls are. Click on the ServiceInstaller1 control. Go to the properties window under events and there you'll find the AfterInstall event.

要创建上述事件处理程序,请转到ProjectInstaller设计器,其中有两个控件。单击ServiceInstaller1控件。转到“事件”下的“属性”窗口,您将在那里找到AfterInstall事件。

Note: Don't put the above code under the AfterInstall event for ServiceProcessInstaller1. It won't work, coming from experience. :)

注意:不要将上述代码放在ServiceProcessInstaller1的AfterInstall事件中。从经验来看,这是行不通的。:)

#8


-1  

The easiest solution is found here install-windows-service-without-installutil-exe by @Hoàng Long

最简单的解决方案是@Hoang Long的install-windows-service- withoutinstallutil -exe

@echo OFF
echo Stopping old service version...
net stop "[YOUR SERVICE NAME]"
echo Uninstalling old service version...
sc delete "[YOUR SERVICE NAME]"

echo Installing service...
rem DO NOT remove the space after "binpath="!
sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto
echo Starting server complete
pause