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

jos*_*ley 30 .net c# windows-services

我有一个安装服务的程序,我希望以后能够让用户选择将启动类型更改为"自动".

操作系统是XP - 如果它有任何区别(Windows API?).

我怎么能在.NET中这样做?C#如果可能的话!:)

Pet*_*lly 53

我写了一篇关于如何使用P/Invoke执行此操作的博客文章.使用我发布的ServiceHelper类,您可以执行以下操作来更改启动模式.

var svc = new ServiceController("ServiceNameGoesHere");  
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic); 
Run Code Online (Sandbox Code Playgroud)

  • @Dave ServiceHelper是我在博文中写的自定义类.说它被弃用没有意义!:) (3认同)
  • 我在几个虚拟机中尝试了这一点,一切似乎在Win 7中运行良好.再次感谢. (2认同)
  • @PeterKelly在博客中您提到“ .NET中有一个托管选项-System.ServiceProcess.ServiceController类,它提供了一些用于管理服务的有用属性和方法。但是,它无法更改服务的启动模式。 ” 为什么会这样呢?我的意思是为什么忽略了此功能?还可以在.NET的ServiceController带MachineName的远程机器上调用吗? (2认同)

Art*_*hur 13

在服务安装程序中,您必须说

[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer 
{
    public ProjectInstaller()
    {
        ...
        this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以在安装期间询问用户,然后设置此值.或者只是在visual studio设计器中设置此属性.


Chr*_*n.K 10

您可以使用OpenService()和ChangeServiceConfig()本机Win32 API来实现此目的.我相信pinvoke.net上有一些信息,当然还有MSDN上的信息.您可能想要查看P/Invoke Interopt Assistant.

  • Downvoter:如果您愿意解释,那会很有帮助. (8认同)

Joh*_*els 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";
            }
        }
    }         
}
Run Code Online (Sandbox Code Playgroud)

//这将使所有服务在域计算机上运行,​​并将"Apple Mobile Device"服务更改为StartMode of Automatic.这两个函数显然应该分开,但使用WMI安装后更改服务启动模式很简单

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想改进这个响应......一种改变指定计算机,服务的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";
            }
        }
    }         
}
Run Code Online (Sandbox Code Playgroud)