Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows services 如何以编程方式在远程设备上停止/启动windows服务?_Windows Services - Fatal编程技术网

Windows services 如何以编程方式在远程设备上停止/启动windows服务?

Windows services 如何以编程方式在远程设备上停止/启动windows服务?,windows-services,Windows Services,我想编写一个控制台或单击一次WinForms应用程序,以编程方式停止和/或启动远程设备上的windows服务 这两个框都在运行.NET 3.5-有什么.NET API可以实现这一点?您可以使用系统管理API(WMI)远程控制服务。WMI是执行管理任务的通用API 但是,对于这个问题,我建议您使用易于使用的System.ServiceProcess.ServiceController类。 您需要具有管理远程机箱上的服务的权限 正如Mehrdad所说,您也可以使用WMI。这两种方法都适用于启动和停止

我想编写一个控制台或单击一次WinForms应用程序,以编程方式停止和/或启动远程设备上的windows服务


这两个框都在运行.NET 3.5-有什么.NET API可以实现这一点?

您可以使用
系统管理
API(WMI)远程控制服务。WMI是执行管理任务的通用API

但是,对于这个问题,我建议您使用易于使用的
System.ServiceProcess.ServiceController
类。

您需要具有管理远程机箱上的服务的权限


正如Mehrdad所说,您也可以使用WMI。这两种方法都适用于启动和停止,但WMI需要更多的编码,如果您不想自己编码,它将为您提供对其他资源的更多访问权。

Microsoft/Sysinternals是一个命令行工具,可以执行您所需的操作。

您也可以使用
sc
命令从命令控制台执行此操作:

 sc <server> start [service name]
 sc <server> stop [service name]
sc启动[服务名称]
sc站点[服务名称]
使用

sc查询|查找“服务名称”
获取服务名称列表

选项
的格式为
\\ServerName

例子
sc\\MyServer stop schedule
将停止计划程序服务。

在C#中:


如果需要获取服务的名称:

从命令行运行此命令:

sc查询

例如,您将看到SQL Server的服务名称为“MSSQL$SQLEXPRESS”

因此,要停止C#中的SQL Server服务,请执行以下操作:


我做了如下工作:

注意:

  • 若你们并没有启动你们的服务,若你们试图停止它将抛出异常
  • 如果在web.config中配置这些内容,则不会出现与配置相关的异常。无需在IIS中执行任何操作


    希望这能有所帮助。

    上面的galets代码片段是一个很好的开始。但是,请记住,它假定服务已经启动,或者更重要的是

    sc.Status == System.ServiceProcess.ServiceControllerStatus.Running
    
    此外,在代码执行期间的某个时刻,调用

    sc.Refresh();
    
    因为属性值(例如ServiceControllerStatus)可能无法反映服务的实际属性。 例如,你可以打电话

    sc.Start();
    
    并在执行此命令时无限期等待

    sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running)
    
    这是我在编写代码时考虑到的一个版本

                //Restart Content Service on DEV. 
            String svcName = "TheServiceName";
            String machineName = "TheMachineName";
            var sc = new System.ServiceProcess.ServiceController(svcName, machineName);
            Console.WriteLine("Stopping Service '{0}' on machine '{1}", svcName, machineName);
            sc.Stop();
            sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);          
    
            //sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
            do
            {
                try
                {
                    sc.Refresh();
                    if (sc.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                    {
                        Console.WriteLine("Code has detected that servive start is pending, waiting 5 seconds to see if status changes..");
                        System.Threading.Thread.Sleep(5000);
                    }
                    else
                    {
                        Console.WriteLine("waiting 5 seconds and retrying start..");
                        System.Threading.Thread.Sleep(5000);
                        Console.WriteLine("Attempt Starting Service '{0}' on machine '{1}", svcName, machineName);
                        sc.Start();
                    }
                }
    
                catch(Exception ex)
                {
                    //If it is already running, then abort do while
                    if (ex.InnerException.Message == "An instance of the service is already running")
                    {
                        Console.WriteLine(ex.InnerException.Message);
                        continue;
                    }
                    Console.WriteLine(ex.InnerException.ToString());
                }
            } while (sc.Status != System.ServiceProcess.ServiceControllerStatus.Running);
    

    这是一个ServiceExtension,可以启动和停止远程pc上的服务

    它可以设置服务的启动类型,甚至设置为“自动(延迟)”

    已修改此版本以在远程计算机上工作

    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.ServiceProcess;
    
    namespace Helpers
    {
        public enum ServiceStartModeEx
        {
            Automatic = 2,
            Manual = 3,
            Disabled = 4,
            DelayedAutomatic = 99
        }
        /// <summary>
        /// Extensions to the ServiceController class.
        /// </summary>
        public static class ServiceControlerExtensions
        {
            /// <summary>
            /// Set the start mode for the service.
            /// </summary>
            /// <param name="serviceController">The service controller.</param>
            /// <param name="mode">The desired start mode.</param>
            public static void SetStartMode(this ServiceController serviceController, ServiceStartModeEx mode)
            {
                IntPtr serviceManagerHandle = OpenServiceManagerHandle(serviceController);
                IntPtr serviceHandle = OpenServiceHandle(serviceController, serviceManagerHandle);
    
                try
                {
                    if (mode == ServiceStartModeEx.DelayedAutomatic)
                    {
                        ChangeServiceStartType(serviceHandle, ServiceStartModeEx.Automatic);
                        ChangeDelayedAutoStart(serviceHandle, true);
                    }
                    else
                    {
                        // Delayed auto-start overrides other settings, so it must be set first.
                        ChangeDelayedAutoStart(serviceHandle, false);
                        ChangeServiceStartType(serviceHandle, mode);
                    }
                }
                finally
                {
                    if (serviceHandle != IntPtr.Zero)
                    {
                        CloseServiceHandle(serviceHandle);
                    }
                    if (serviceManagerHandle != IntPtr.Zero)
                    {
                        CloseServiceHandle(serviceManagerHandle);
                    }
                }
            }
    
            private static IntPtr OpenServiceHandle(ServiceController serviceController, IntPtr serviceManagerHandle)
            {
                var serviceHandle = OpenService(
                                                serviceManagerHandle,
                                                serviceController.ServiceName,
                                                SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
    
                if (serviceHandle == IntPtr.Zero)
                {
                    throw new ExternalException("Open Service Error");
                }
                return serviceHandle;
            }
    
            private static IntPtr OpenServiceManagerHandle(ServiceController serviceController)
            {
                var machineName = string.IsNullOrWhiteSpace(serviceController.MachineName)
                    ? null
                    : serviceController.MachineName;
                IntPtr serviceManagerHandle = OpenSCManager(machineName, null, SC_MANAGER_ALL_ACCESS);
                if (serviceManagerHandle == IntPtr.Zero)
                {
                    throw new ExternalException("Open Service Manager Error");
                }
                return serviceManagerHandle;
            }
    
            private static void ChangeServiceStartType(IntPtr serviceHandle, ServiceStartModeEx mode)
            {
                bool result = ChangeServiceConfig(
                                                 serviceHandle,
                                                 SERVICE_NO_CHANGE,
                                                 (uint)mode,
                                                 SERVICE_NO_CHANGE,
                                                 null,
                                                 null,
                                                 IntPtr.Zero,
                                                 null,
                                                 null,
                                                 null,
                                                 null);
    
                if (result == false)
                {
                    ThrowLastWin32Error("Could not change service start type");
                }
            }
    
            private static void ChangeDelayedAutoStart(IntPtr hService, bool delayed)
            {
                // Create structure that contains DelayedAutoStart property.
                SERVICE_DELAYED_AUTO_START_INFO info = new SERVICE_DELAYED_AUTO_START_INFO();
    
                // Set the DelayedAutostart property in that structure.
                info.fDelayedAutostart = delayed;
    
                // Allocate necessary memory.
                IntPtr hInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SERVICE_DELAYED_AUTO_START_INFO)));
    
                // Convert structure to pointer.
                Marshal.StructureToPtr(info, hInfo, true);
    
                // Change the configuration.
                bool result = ChangeServiceConfig2(hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, hInfo);
    
                // Release memory.
                Marshal.FreeHGlobal(hInfo);
    
                if (result == false)
                {
                    ThrowLastWin32Error("Could not set service to delayed automatic");
                }
            }
    
            private static void ThrowLastWin32Error(string messagePrefix)
            {
                int nError = Marshal.GetLastWin32Error();
                var win32Exception = new Win32Exception(nError);
                string message = string.Format("{0}: {1}", messagePrefix, win32Exception.Message);
                throw new ExternalException(message);
            }
    
            [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            private static extern IntPtr OpenService(
                IntPtr hSCManager,
                string lpServiceName,
                uint dwDesiredAccess);
    
            [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode,
                SetLastError = true)]
            private static extern IntPtr OpenSCManager(
                string machineName,
                string databaseName,
                uint dwAccess);
    
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            private static extern Boolean ChangeServiceConfig(
                IntPtr hService,
                UInt32 nServiceType,
                UInt32 nStartType,
                UInt32 nErrorControl,
                String lpBinaryPathName,
                String lpLoadOrderGroup,
                IntPtr lpdwTagId,
                [In] char[] lpDependencies,
                String lpServiceStartName,
                String lpPassword,
                String lpDisplayName);
    
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool ChangeServiceConfig2(
                IntPtr hService,
                int dwInfoLevel,
                IntPtr lpInfo);
    
            [DllImport("advapi32.dll", EntryPoint = "CloseServiceHandle")]
            private static extern int CloseServiceHandle(IntPtr hSCObject);
    
            private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
            private const uint SERVICE_QUERY_CONFIG = 0x00000001;
            private const uint SERVICE_CHANGE_CONFIG = 0x00000002;
            private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
    
            private const int SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3;
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
            private struct SERVICE_DELAYED_AUTO_START_INFO
            {
                public bool fDelayedAutostart;
            }
        }
    }
    
    serviceName=“服务的名称”

    machineName=“远程/本地主机的名称”

    你可以停止这样的服务

     using System.ServiceProcess;
    
    var service = new ServiceController(serviceName, machineName);
    try
    {
        if (service.CanStop)
        {
            service.SetStartMode(ServiceStartModeEx.Disabled);
            service.Stop();
    
        }
    }
    
    finally
    {
        service.Close();
    }
    
    要授予用户在远程pc上启动和停止服务的权限,您必须设置一些服务权限,您可以通过谷歌搜索subinacl.exe是什么以及在哪里下载它

    C:\Program Files (x86)\Windows Resource Kits\Tools>subinacl.exe /service SERVICENAME /grant=MACHINENAME\USERNAME=F
    

    我已经在我的项目中编写了这个代码,但我一直在调试模式下运行,逐步查找它不再工作的原因。我得到“.无法在计算机上启动服务”。InnerException,“服务没有及时响应启动或控制请求”,但它确实在5秒内从管理控制台以完全相同的二进制文件启动!!为我工作。如果您试图对远程计算机执行此操作,并且rpc调用失败或无法连接到远程计算机上的服务控制管理器,请确保在调用WaitForStatus时,将合理的时间跨度作为第二个参数传递(重载)。我认为SC在抛出异常之前会等待服务启动或停止长达2.5分钟,因此我一直在使用2分钟。我得到的异常如下
    System.ServiceProcess.dll中发生了类型为“System.InvalidOperationException”的未处理异常。其他信息:无法在计算机上打开服务控制管理器。此操作可能需要其他权限。
    程序集引用显然是“System.ServiceProcess”
                //Restart Content Service on DEV. 
            String svcName = "TheServiceName";
            String machineName = "TheMachineName";
            var sc = new System.ServiceProcess.ServiceController(svcName, machineName);
            Console.WriteLine("Stopping Service '{0}' on machine '{1}", svcName, machineName);
            sc.Stop();
            sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);          
    
            //sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
            do
            {
                try
                {
                    sc.Refresh();
                    if (sc.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                    {
                        Console.WriteLine("Code has detected that servive start is pending, waiting 5 seconds to see if status changes..");
                        System.Threading.Thread.Sleep(5000);
                    }
                    else
                    {
                        Console.WriteLine("waiting 5 seconds and retrying start..");
                        System.Threading.Thread.Sleep(5000);
                        Console.WriteLine("Attempt Starting Service '{0}' on machine '{1}", svcName, machineName);
                        sc.Start();
                    }
                }
    
                catch(Exception ex)
                {
                    //If it is already running, then abort do while
                    if (ex.InnerException.Message == "An instance of the service is already running")
                    {
                        Console.WriteLine(ex.InnerException.Message);
                        continue;
                    }
                    Console.WriteLine(ex.InnerException.ToString());
                }
            } while (sc.Status != System.ServiceProcess.ServiceControllerStatus.Running);
    
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.ServiceProcess;
    
    namespace Helpers
    {
        public enum ServiceStartModeEx
        {
            Automatic = 2,
            Manual = 3,
            Disabled = 4,
            DelayedAutomatic = 99
        }
        /// <summary>
        /// Extensions to the ServiceController class.
        /// </summary>
        public static class ServiceControlerExtensions
        {
            /// <summary>
            /// Set the start mode for the service.
            /// </summary>
            /// <param name="serviceController">The service controller.</param>
            /// <param name="mode">The desired start mode.</param>
            public static void SetStartMode(this ServiceController serviceController, ServiceStartModeEx mode)
            {
                IntPtr serviceManagerHandle = OpenServiceManagerHandle(serviceController);
                IntPtr serviceHandle = OpenServiceHandle(serviceController, serviceManagerHandle);
    
                try
                {
                    if (mode == ServiceStartModeEx.DelayedAutomatic)
                    {
                        ChangeServiceStartType(serviceHandle, ServiceStartModeEx.Automatic);
                        ChangeDelayedAutoStart(serviceHandle, true);
                    }
                    else
                    {
                        // Delayed auto-start overrides other settings, so it must be set first.
                        ChangeDelayedAutoStart(serviceHandle, false);
                        ChangeServiceStartType(serviceHandle, mode);
                    }
                }
                finally
                {
                    if (serviceHandle != IntPtr.Zero)
                    {
                        CloseServiceHandle(serviceHandle);
                    }
                    if (serviceManagerHandle != IntPtr.Zero)
                    {
                        CloseServiceHandle(serviceManagerHandle);
                    }
                }
            }
    
            private static IntPtr OpenServiceHandle(ServiceController serviceController, IntPtr serviceManagerHandle)
            {
                var serviceHandle = OpenService(
                                                serviceManagerHandle,
                                                serviceController.ServiceName,
                                                SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
    
                if (serviceHandle == IntPtr.Zero)
                {
                    throw new ExternalException("Open Service Error");
                }
                return serviceHandle;
            }
    
            private static IntPtr OpenServiceManagerHandle(ServiceController serviceController)
            {
                var machineName = string.IsNullOrWhiteSpace(serviceController.MachineName)
                    ? null
                    : serviceController.MachineName;
                IntPtr serviceManagerHandle = OpenSCManager(machineName, null, SC_MANAGER_ALL_ACCESS);
                if (serviceManagerHandle == IntPtr.Zero)
                {
                    throw new ExternalException("Open Service Manager Error");
                }
                return serviceManagerHandle;
            }
    
            private static void ChangeServiceStartType(IntPtr serviceHandle, ServiceStartModeEx mode)
            {
                bool result = ChangeServiceConfig(
                                                 serviceHandle,
                                                 SERVICE_NO_CHANGE,
                                                 (uint)mode,
                                                 SERVICE_NO_CHANGE,
                                                 null,
                                                 null,
                                                 IntPtr.Zero,
                                                 null,
                                                 null,
                                                 null,
                                                 null);
    
                if (result == false)
                {
                    ThrowLastWin32Error("Could not change service start type");
                }
            }
    
            private static void ChangeDelayedAutoStart(IntPtr hService, bool delayed)
            {
                // Create structure that contains DelayedAutoStart property.
                SERVICE_DELAYED_AUTO_START_INFO info = new SERVICE_DELAYED_AUTO_START_INFO();
    
                // Set the DelayedAutostart property in that structure.
                info.fDelayedAutostart = delayed;
    
                // Allocate necessary memory.
                IntPtr hInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SERVICE_DELAYED_AUTO_START_INFO)));
    
                // Convert structure to pointer.
                Marshal.StructureToPtr(info, hInfo, true);
    
                // Change the configuration.
                bool result = ChangeServiceConfig2(hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, hInfo);
    
                // Release memory.
                Marshal.FreeHGlobal(hInfo);
    
                if (result == false)
                {
                    ThrowLastWin32Error("Could not set service to delayed automatic");
                }
            }
    
            private static void ThrowLastWin32Error(string messagePrefix)
            {
                int nError = Marshal.GetLastWin32Error();
                var win32Exception = new Win32Exception(nError);
                string message = string.Format("{0}: {1}", messagePrefix, win32Exception.Message);
                throw new ExternalException(message);
            }
    
            [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            private static extern IntPtr OpenService(
                IntPtr hSCManager,
                string lpServiceName,
                uint dwDesiredAccess);
    
            [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode,
                SetLastError = true)]
            private static extern IntPtr OpenSCManager(
                string machineName,
                string databaseName,
                uint dwAccess);
    
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            private static extern Boolean ChangeServiceConfig(
                IntPtr hService,
                UInt32 nServiceType,
                UInt32 nStartType,
                UInt32 nErrorControl,
                String lpBinaryPathName,
                String lpLoadOrderGroup,
                IntPtr lpdwTagId,
                [In] char[] lpDependencies,
                String lpServiceStartName,
                String lpPassword,
                String lpDisplayName);
    
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool ChangeServiceConfig2(
                IntPtr hService,
                int dwInfoLevel,
                IntPtr lpInfo);
    
            [DllImport("advapi32.dll", EntryPoint = "CloseServiceHandle")]
            private static extern int CloseServiceHandle(IntPtr hSCObject);
    
            private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
            private const uint SERVICE_QUERY_CONFIG = 0x00000001;
            private const uint SERVICE_CHANGE_CONFIG = 0x00000002;
            private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
    
            private const int SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3;
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
            private struct SERVICE_DELAYED_AUTO_START_INFO
            {
                public bool fDelayedAutostart;
            }
        }
    }
    
     using System.ServiceProcess;
    
     var service = new ServiceController(serviceName, machineName);
     try
     {
         service.SetStartMode(ServiceStartModeEx.DelayedAutomatic);
         service.Start();
     }
    
     finally
     {
         service.Close();
     }
    
    var service = new ServiceController(serviceName, machineName);
    try
    {
        if (service.CanStop)
        {
            service.SetStartMode(ServiceStartModeEx.Disabled);
            service.Stop();
    
        }
    }
    
    finally
    {
        service.Close();
    }
    
    C:\Program Files (x86)\Windows Resource Kits\Tools>subinacl.exe /service SERVICENAME /grant=MACHINENAME\USERNAME=F