我有一个安装服务的程序,我希望以后可以让用户选择将启动类型更改为“自动”。
操作系统是XP - 如果它有所不同(Windows API?)。
我如何在.NET中执行此操作? C#如果可能的话! :)
答案 0 :(得分:52)
我用P / Invoke编写了blog post如何做到这一点。使用我发布的ServiceHelper类,您可以执行以下操作来更改启动模式。
var svc = new ServiceController("ServiceNameGoesHere");
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic);
答案 1 :(得分:12)
在服务安装程序中,您必须说
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
...
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
}
}
您也可以在安装期间询问用户,然后设置此值。或者只是在visual studio designer中设置此属性。
答案 2 :(得分:10)
您可以使用OpenService()和ChangeServiceConfig()本机Win32 API来实现此目的。我相信pinvoke.net上有一些信息,当然还有MSDN。您可能需要查看P/Invoke Interopt Assistant。
答案 3 :(得分:6)
您可以使用WMI查询所有服务,然后将服务名称与输入的用户值
相匹配找到服务后,只需更改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";
}
}
}
}
我想改进此响应...一种更改指定计算机的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);
}
}
答案 4 :(得分:2)
在ProjectInstaller.cs中,单击/选择设计图面上的Service1组件。在属性windo中有一个startType属性供您设置。
答案 5 :(得分:2)
如何使用c:\ windows \ system32 \ sc.exe来做到这一点?
在VB.NET代码中,使用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
结束功能
答案 6 :(得分:0)
ServiceInstaller myInstaller = new System.ServiceProcess.ServiceInstaller();
myInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
答案 7 :(得分:0)
您可以通过将ServiceInstaller.StartType属性设置为您获得的任何值来在服务的Installer类中执行此操作(您可能必须在自定义操作中执行此操作,因为您希望用户指定)或者您可以修改服务的“开始”REG_DWORD条目,值2是自动的,3是手动的。它在HKEY_LOCAL_MACHINE \ SYSTEM \ Services \ YourServiceName
中答案 8 :(得分:-2)
一种方法是卸载以前的服务,并直接从C#应用程序安装带有更新参数的新服务。
您的应用中需要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);
}
}
并重新安装服务只需使用这两行。
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });