C# 如何在 .NET 中更改 Windows 服务的启动类型(安装后)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1477618/
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 do I change a Windows Service's startup type in .NET (post-install)?
提问by joshcomley
I have a program that installs a service, and I'd like to be able to give the user the option later on to change the startup type to "Automatic".
我有一个安装服务的程序,我希望能够让用户稍后选择将启动类型更改为“自动”。
The OS is XP - if it makes any difference (Windows APIs?).
操作系统是 XP - 如果它有任何区别(Windows API?)。
How can I do this in .NET? C# if possible! :)
我怎样才能在 .NET 中做到这一点?如果可能的话,C#!:)
采纳答案by Christian.K
You can use the OpenService() and ChangeServiceConfig() native Win32 APIs for that purpose. I believe that there is some information on pinvoke.netand of course on MSDN. You might want to check out the P/Invoke Interopt Assistant.
为此,您可以使用 OpenService() 和 ChangeServiceConfig() 本机 Win32 API。我相信pinvoke.net上有一些信息,当然还有MSDN 上的信息。您可能想查看P/Invoke Interopt Assistant。
回答by Arthur
In the service installer you have to say
在服务安装程序中,您必须说
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
...
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
}
}
You could also ask the user during installation and then set this value. Or just set this property in the visual studio designer.
您也可以在安装过程中询问用户,然后设置此值。或者只是在 Visual Studio 设计器中设置此属性。
回答by CSharpAtl
ServiceInstaller myInstaller = new System.ServiceProcess.ServiceInstaller();
myInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
回答by Matt Wrock
In ProjectInstaller.cs, click/select the Service1 component on the design surface. In the properties windo there is a startType property for you to set this.
在 ProjectInstaller.cs 中,单击/选择设计图面上的 Service1 组件。在属性窗口中有一个 startType 属性供您设置。
回答by lubos hasko
One way would be to uninstall previous service and install new one with updated parameters directly from your C# application.
一种方法是直接从 C# 应用程序卸载以前的服务并安装带有更新参数的新服务。
You will need WindowsServiceInstaller
in your app.
您将需要WindowsServiceInstaller
在您的应用程序中。
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
{
public WindowsServiceInstaller()
{
ServiceInstaller si = new ServiceInstaller();
si.StartType = ServiceStartMode.Automatic; // get this value from some global variable
si.ServiceName = @"YOUR APP";
si.DisplayName = @"YOUR APP";
this.Installers.Add(si);
ServiceProcessInstaller spi = new ServiceProcessInstaller();
spi.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
spi.Username = null;
spi.Password = null;
this.Installers.Add(spi);
}
}
and to reinstall service just use these two lines.
并重新安装服务只需使用这两行。
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
回答by HasaniH
You can do it in the Installer class for the service by setting ServiceInstaller.StartType property to whatever value you get (you'll probably have to do this in a custom action since you want the user to specify) or you can modify the Service's "Start" REG_DWORD entry, the value 2 is automatic and 3 is manual. Its in HKEY_LOCAL_MACHINE\SYSTEM\Services\YourServiceName
您可以在服务的安装程序类中通过将 ServiceInstaller.StartType 属性设置为您获得的任何值(您可能必须在自定义操作中执行此操作,因为您希望用户指定)或者您可以修改服务的“ Start” REG_DWORD 条目,值 2 是自动的,3 是手动的。它在 HKEY_LOCAL_MACHINE\SYSTEM\Services\YourServiceName
回答by Peter Kelly
I wrote a blog poston how to do this using P/Invoke. Using the ServiceHelper class from my post you can do the following to change the Start Mode.
我写了一篇关于如何使用 P/Invoke 做到这一点的博客文章。使用我帖子中的 ServiceHelper 类,您可以执行以下操作来更改启动模式。
var svc = new ServiceController("ServiceNameGoesHere");
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic);
回答by John Bartels
You can use WMI to query all services and then match the service name to the inputted user value
您可以使用 WMI 查询所有服务,然后将服务名称与输入的用户值进行匹配
Once the service has been found just change the StartMode Property
找到服务后,只需更改 StartMode 属性
if(service.Properties["Name"].Value.ToString() == userInputValue)
{
service.Properties["StartMode"].Value = "Automatic";
//service.Properties["StartMode"].Value = "Manual";
}
//This will get all of the Services running on a Domain Computer and change the "Apple Mobile Device" Service to the StartMode of Automatic. These two functions should obviously be separated, but it is simple to change a service start mode after installation using WMI
private void getServicesForDomainComputer(string computerName)
{
ConnectionOptions co1 = new ConnectionOptions();
co1.Impersonation = ImpersonationLevel.Impersonate;
//this query could also be: ("select * from Win32_Service where name = '" + serviceName + "'");
ManagementScope scope = new ManagementScope(@"\" + computerName + @"\root\cimv2");
scope.Options = co1;
SelectQuery query = new SelectQuery("select * from Win32_Service");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
ManagementObjectCollection collection = searcher.Get();
foreach (ManagementObject service in collection)
{
//the following are all of the available properties
//boolean AcceptPause
//boolean AcceptStop
//string Caption
//uint32 CheckPoint
//string CreationClassName
//string Description
//boolean DesktopInteract
//string DisplayName
//string ErrorControl
//uint32 ExitCode;
//datetime InstallDate;
//string Name
//string PathName
//uint32 ProcessId
//uint32 ServiceSpecificExitCode
//string ServiceType
//boolean Started
//string StartMode
//string StartName
//string State
//string Status
//string SystemCreationClassName
//string SystemName;
//uint32 TagId;
//uint32 WaitHint;
if(service.Properties["Name"].Value.ToString() == "Apple Mobile Device")
{
service.Properties["StartMode"].Value = "Automatic";
}
}
}
}
I wanted to improve this response... One method to change startMode for Specified computer, service:
我想改进此响应...更改指定计算机、服务的 startMode 的一种方法:
public void changeServiceStartMode(string hostname, string serviceName, string startMode)
{
try
{
ManagementObject classInstance =
new ManagementObject(@"\" + hostname + @"\root\cimv2",
"Win32_Service.Name='" + serviceName + "'",
null);
// Obtain in-parameters for the method
ManagementBaseObject inParams = classInstance.GetMethodParameters("ChangeStartMode");
// Add the input parameters.
inParams["StartMode"] = startMode;
// Execute the method and obtain the return values.
ManagementBaseObject outParams = classInstance.InvokeMethod("ChangeStartMode", inParams, null);
// List outParams
//Console.WriteLine("Out parameters:");
//richTextBox1.AppendText(DateTime.Now.ToString() + ": ReturnValue: " + outParams["ReturnValue"]);
}
catch (ManagementException err)
{
//richTextBox1.AppendText(DateTime.Now.ToString() + ": An error occurred while trying to execute the WMI method: " + err.Message);
}
}
回答by Chou George
How about make use of c:\windows\system32\sc.exe to do that ?!
如何利用 c:\windows\system32\sc.exe 来做到这一点?!
In VB.NET Codes, use System.Diagnostics.Process to call sc.exe to change the startup mode of a windows service. following is my sample code
在 VB.NET Codes 中,使用 System.Diagnostics.Process 调用 sc.exe 来更改 Windows 服务的启动模式。以下是我的示例代码
Public Function SetStartModeToDisabled(ByVal ServiceName As String) As Boolean
Dim sbParameter As New StringBuilder
With sbParameter
.Append("config ")
.AppendFormat("""{0}"" ", ServiceName)
.Append("start=disabled")
End With
Dim processStartInfo As ProcessStartInfo = New ProcessStartInfo()
Dim scExeFilePath As String = String.Format("{0}\sc.exe", Environment.GetFolderPath(Environment.SpecialFolder.System))
processStartInfo.FileName = scExeFilePath
processStartInfo.Arguments = sbParameter.ToString
processStartInfo.UseShellExecute = True
Dim process As Process = process.Start(processStartInfo)
process.WaitForExit()
Return process.ExitCode = 0
End Function
结束函数