如何在安装后立即启动 .NET Windows 服务?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1195478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make a .NET Windows Service start right after the installation?
提问by Jader Dias
Besides the service.StartType = ServiceStartMode.Automatic my service does not start after installation
除了 service.StartType = ServiceStartMode.Automatic 我的服务在安装后没有启动
Solution
解决方案
Inserted this code on my ProjectInstaller
在我的 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.
采纳答案by ScottTx
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
回答by Matt Davis
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?),但我确实在网上找到了一个解决方案,它允许您通过实际运行服务本身来安装和启动服务。这是一步一步:
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(); } } }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; }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; } } }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
-installcommand line argument to install and start your service.
Main()像这样构建服务的功能: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(); } } }这是支持代码:
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; }继续支持代码...
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; } } }此时,在目标计算机上安装服务后,只需使用
-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.
我想我已经涵盖了所有内容,但是如果您发现这不起作用,请告诉我,以便我可以更新答案。
回答by Francis B.
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
InstallShield 或 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,这些应用程序提供启动服务的选项。根据 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>
回答by Otávio Décio
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 创作工具。
回答by ScottTx
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”。无论哪种方式都有效。
回答by Matt
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....
这并不理想,但它有效......
回答by goku_da_master
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 的答案中,这是启动服务的实际代码,如果您以Microsoft 方式进行操作(即使用安装项目等...)
(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.
要创建上述事件处理程序,请转到 2 个控件所在的 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 事件下。从经验来看,这是行不通的。:)
回答by Robert Green MBA
The easiest solution is found here install-windows-service-without-installutil-exeby @Hoàng Long
最简单的解决方案是@Hoàng Long在此处找到install-windows-service-without-installutil-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

