如何在.NET中更改Windows服务启动类型(安装后)?

时间:2009-09-25 14:28:16

标签: c# .net windows-services

我有一个安装服务的程序,我希望以后可以让用户选择将启动类型更改为“自动”。

操作系统是XP - 如果它有所不同(Windows API?)。

我如何在.NET中执行此操作? C#如果可能的话! :)

9 个答案:

答案 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 });