C# 如何更改.NET中Windows服务的启动类型(安装后)?
我有一个安装服务的程序,我希望以后能够给用户提供将启动类型更改为自动的选项 操作系统是XP-如果它对Windows API有什么影响C# 如何更改.NET中Windows服务的启动类型(安装后)?,c#,.net,windows-services,C#,.net,Windows Services,我有一个安装服务的程序,我希望以后能够给用户提供将启动类型更改为自动的选项 操作系统是XP-如果它对Windows API有什么影响 如何在.NET中执行此操作?C如果可能的话!: 在服务安装程序中,您必须说 [RunInstaller(true)] public class ProjectInstaller : System.Configuration.Install.Installer { public ProjectInstaller() { ...
如何在.NET中执行此操作?C如果可能的话!: 在服务安装程序中,您必须说
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
...
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
}
}
您也可以在安装过程中询问用户,然后设置此值。或者在visual studio designer中设置此属性。在ProjectInstaller.cs中,单击/选择设计图面上的Service1组件。在属性windo中有一个startType属性供您设置此属性。一种方法是卸载以前的服务,然后直接从C应用程序安装带有更新参数的新服务
ServiceInstaller myInstaller = new System.ServiceProcess.ServiceInstaller();
myInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
您的应用程序中需要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 });
您可以在服务的Installer类中通过将ServiceInstaller.StartType属性设置为您获得的任何值来执行此操作。您可能需要在自定义操作中执行此操作,因为您希望用户指定或您可以修改服务的Start REG_DWORD条目,值2为自动,值3为手动。在HKEY_LOCAL_MACHINE\SYSTEM\Services\YourServiceName中,您可以使用OpenService和ChangeServiceConfig本机Win32 API实现此目的。我相信有一些关于,当然还有关于的信息。您可能想查看。我写了一篇关于如何使用p/Invoke实现这一点的文章。使用我文章中的ServiceHelper类,您可以执行以下操作来更改启动模式
var svc = new ServiceController("ServiceNameGoesHere");
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic);
您可以使用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);
}
}
使用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
结束功能Ah正常,因此不卸载服务就无法进行后期安装?要进行后期安装吗?然后您必须使用WMI。修改注册表将是在安装后更改启动类型的最佳方法。您可以使用Microsoft.Win32.Registry类来执行此操作。不要这样做。像这样的黑客行为正是为什么在较新的windows版本中存在大量兼容性问题的原因。有完全合理的API来实现这一点——只是它们没有得到管理。然而,当你知道你在windows上时,你知道在这两种情况下都是注册表或API/未被管理的,这不重要。如何使用注册表作为黑客?API修改注册表,它只是一个抽象层……好吧,如果他们需要或想要更改注册表的逻辑布局以进行服务注册,那么您的代码将中断。所以,除非注册表的这一部分是明确的文档,我怀疑它是,它应该是禁止的,除了手动故障排除,也许。此外,您确定服务控制管理器实际上会识别您直接对注册表所做的更改,而不是通过官方API所做的更改吗?可能会有一大堆问题,只有在你没有预料到的时候才会浮出水面。只是不要走这条路。好吧,看到API改变了注册表值,我会说你建议的改变会破坏我的代码,也会破坏API。你有没有看过你链接的API文档?因为他们提到了注册表的使用……我在几个虚拟机上试用了这个方法,在Win7中似乎一切都很好。再次感谢。@PeterKelly在您的博客中提到,.NET中有一个托管选项-System.ServiceProcess.ServiceController类,它公开了一些用于管理服务的有用属性和方法。但是,它无法更改服务的启动模式。为什么会这样?我的意思是为什么这个功能被忽略了?也可以在远程计算机上调用它,如.NET的ServiceController takes MachineName?ServiceHelper现在似乎已被弃用=@Dave ServiceHelper是我在博客文章中编写的自定义类。说它不受欢迎是没有道理的!:还有一件事。。。如果要更改其他计算机上的服务,请在ServiceController类上设置MachineName,然后将ChangeStartMode方法更改为以下内容:public static void ChangeStartModes服务控制器svc,ServiceStartMode模式{string machineName=string.IsNullOrWhiteSpacesvc.machineName?null:svc.machineName;var scManagerHandle=OpenSCManagermachineName,null,SC_MANAGER_ALL_ACCESS。。。