【发布时间】:2009-06-24 06:33:08
【问题描述】:
我有一个使用 InstallUtil.exe 安装的 Windows 服务。即使我将启动方法设置为自动,安装时服务也不会启动,我必须手动打开服务并单击启动。有没有办法通过命令行启动它,或者通过服务的代码?
【问题讨论】:
标签: c# windows-services
我有一个使用 InstallUtil.exe 安装的 Windows 服务。即使我将启动方法设置为自动,安装时服务也不会启动,我必须手动打开服务并单击启动。有没有办法通过命令行启动它,或者通过服务的代码?
【问题讨论】:
标签: c# windows-services
在您的 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 时,它将自动安装并启动服务。
【讨论】:
ServiceController 包装在 using 语句中也不会有什么坏处。
ServiceInstaller 变量。此类应实现System.Configuration.Install.Installer。请参阅此msdn guide 了解更多信息。
serviceInstaller是事件处理程序中sender所引用的ServiceInstaller对象,通常在ServiceInstaller()构造函数中实例化。因此,您可以在 using 语句之前添加 ServiceInstaller serviceInstaller = (ServiceInstaller)sender;。
稍作重构后,这是一个完整的自动启动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();
}
}
}
【讨论】:
下面的命令怎么样?
net start "<service name>"
net stop "<service name>"
【讨论】:
控制服务的编程选项:
StartService 方法。这适用于您需要能够执行其他处理(例如选择哪个服务)的情况。RunspaceInvoke 执行Start-Service 或通过创建自己的Runspace 并使用其CreatePipeline 方法来执行。这适用于您需要能够使用比 WMI 更简单的编码模型执行其他处理(例如选择哪个服务)但取决于安装的 PSH 的情况。ServiceController
【讨论】:
您可以使用以下命令行启动服务:
net start *servicename*
【讨论】:
这是在 Visual Studio 中使用生成的ProjectInstaller 的过程和代码:
ProjectInstaller(它应该在创建安装程序时自动打开)并设置生成的serviceProcessInstaller1(例如Account:LocalSystem)和serviceInstaller1(例如StartType:Automatic)的属性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();
}
}
}
【讨论】:
使用ServiceController 从代码启动您的服务。
更新:从命令行启动服务更正确的方法是使用“sc”(Service Controller)命令而不是“net”。
【讨论】:
尽管完全遵循了接受的答案,但我仍然无法启动服务 - 相反,我在安装过程中收到一条失败消息,指出刚刚安装的服务无法启动,因为它不存在,尽管使用this.serviceInstaller.ServiceName 而不是文字...
我最终找到了一个使用命令行的替代解决方案:
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();
}
【讨论】:
自动启动是指服务在Windows启动时自动启动。正如其他人所提到的,要从控制台启动它,您应该使用 ServiceController。
【讨论】:
可以使用ServiceController的@987654321@方法
类来获取所有服务的数组。然后,通过检查每个服务的 @987654323@ 属性找到您的服务。找到服务后,调用@987654324@ 方法启动它。
您还应该检查@987654325@ 属性以查看它在调用 start 之前已经处于什么状态(它可能正在运行、暂停、停止等)。
【讨论】:
你破坏了你的设计师。重新添加您的安装程序组件。它应该有一个 serviceInstaller 和一个 serviceProcessInstaller。属性 Startup Method 设置为 Automatic 的 serviceInstaller 将在安装时和每次重启后启动。
【讨论】:
请注意:您可能使用表单界面以不同方式设置服务,以添加服务安装程序和项目安装程序。在这种情况下,将 serviceInstaller.ServiceName 替换为“来自设计师的名称”.ServiceName。
在这种情况下,您也不需要私有成员。
感谢您的帮助。
【讨论】:
这对我来说没问题。在 Service 项目中添加到 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();
}
}
}
【讨论】: