Automatically start a Windows Service on install

我有一个使用 InstallUtil.exe 安装的 Windows 服务。即使我已经将启动方法设置为自动,服务不会在安装时启动,我必须手动打开服务并单击开始。是否有方法通过命令行启动它,或者通过服务代码启动它?

112889 次浏览

自动启动意味着在 Windows 启动时自动启动服务。正如其他人所提到的,要从控制台启动它,您应该使用 ServiceController。

听从命令怎么样?

net start "<service name>"
net stop "<service name>"

可以使用以下命令行启动服务:

net start *servicename*

Use 服务控制器 to start your service from code.

更新: 从命令行启动服务的更正确方法是使用“ sc”(服务总监)命令而不是“ net”。

您可以使用 < a href = “ http://msdn.microsoft.com/en-us/library/system.serviceprocess.ServiceController.aspx”rel = “ nofollow noReferrer”> ServiceController 的 GetServices方法 类获取所有服务的数组。然后,通过检查每个服务的 ServiceName属性来查找您的服务。找到服务后,调用 Start方法启动它。

You should also check the Status property to see what state it is already in before calling start (it may be running, paused, stopped, etc..).

控制服务的方案选择:

  • 可以使用本机代码 “开始服务”。最大限度地控制,尽可能减少依赖性,但工作量最大。
  • WMI: Win32 _ Service has a StartService method. This is good for cases where you need to be able to perform other processing (e.g. to select which service).
  • PowerShell: 通过 RunspaceInvoke或创建自己的 Runspace并使用其 CreatePipeline方法执行 Start-Service。这对于需要使用比 WMI 更简单的编码模型来执行其他处理(例如选择哪个服务)的情况很有用,但这取决于安装的 PSH。
  • A .NET application can use ServiceController

在 Installer 类中,为 AfterInstall 事件添加一个处理程序。然后可以在事件处理程序中调用 ServiceController 来启动服务。

using System.ServiceProcess;
public ServiceInstaller()
{
//... Installer code here
this.AfterInstall += new InstallEventHandler(ServiceInstaller_AfterInstall);
}


void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
ServiceInstaller serviceInstaller = (ServiceInstaller)sender;


using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
{
sc.Start();
}
}

现在,当您在安装程序上运行 InstallUtil 时,它将安装并自动启动服务。

经过一些重构之后,这是一个带有自动启动的完整 Windows 服务安装程序的示例:

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;


namespace Example.of.name.space
{
[RunInstaller(true)]
public partial class ServiceInstaller : Installer
{
private readonly ServiceProcessInstaller processInstaller;
private readonly System.ServiceProcess.ServiceInstaller serviceInstaller;


public ServiceInstaller()
{
InitializeComponent();
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new System.ServiceProcess.ServiceInstaller();


// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;


// Service will have Automatic Start Type
serviceInstaller.StartType = ServiceStartMode.Automatic;


serviceInstaller.ServiceName = "Windows Automatic Start Service";


Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
serviceInstaller.AfterInstall += ServiceInstaller_AfterInstall;
}
private void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
ServiceController sc = new ServiceController("Windows Automatic Start Service");
sc.Start();
}
}
}

你腐蚀了你的设计师。重新添加安装程序组件。它应该有一个 serviceInstaller 和一个 serviceProcessInstaller。设置为“自动启动方法”属性的 serviceInstaller 将在安装时和每次重新启动后启动。

尽管按照接受的答案,我仍然无法启动服务——相反,在安装过程中,我收到一条失败消息,说刚刚安装的服务无法启动,因为它不存在,尽管使用的是 this.serviceInstaller.ServiceName而不是文字..。

I eventually found an alternative solution that makes use of the command line:

private void serviceInstaller_AfterInstall(object sender, InstallEventArgs e) {
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C sc start " + this.serviceInstaller.ServiceName;


Process process = new Process();
process.StartInfo = startInfo;
process.Start();
}

Just a note: You might have set up your service differently using the forms interface to add a service installer and project installer. In that case replace where it says serviceInstaller.ServiceName with "name from designer".ServiceName.

在这种情况下,您也不需要私有成员。

谢谢你的帮助。

下面是在 VisualStudio 中使用生成的 ProjectInstaller的过程和代码:

  1. Create Windows Service project in Visual Studio
  2. Generate installers to the service
  3. 在设计编辑器中打开 ProjectInstaller(它应该在创建安装程序时自动打开) ,并设置生成的 serviceProcessInstaller1(例如 Account: LocalSystem)和 serviceInstaller1(例如 StartType: auto)的属性
  4. 在代码编辑器中打开 ProjectInstaller(在设计编辑器中按 F7)并将事件处理程序添加到 ServiceInstaller.AfterInstall-请参阅下面的代码。它将在安装后启动服务。

ProjectInstaller 类:

using System.ServiceProcess;




[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
InitializeComponent(); //generated code including property settings from previous steps
this.serviceInstaller1.AfterInstall += Autorun_AfterServiceInstall; //use your ServiceInstaller name if changed from serviceInstaller1
}


void Autorun_AfterServiceInstall(object sender, InstallEventArgs e)
{
ServiceInstaller serviceInstaller = (ServiceInstaller)sender;
using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
{
sc.Start();
}
}
}

This is OK for me. In Service project add to Installer.cs

[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
InitializeComponent();
}
 

protected override void OnAfterInstall(IDictionary savedState)
{
base.OnAfterInstall(savedState);
 

//The following code starts the services after it is installed.
using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
{
serviceController.Start();
}
}
}