• c# Start/Stop/Check Status远程计算机的Windows Service


     1 static void Main(string[] args)
     2 {
     3     ConnectionOptions op = new ConnectionOptions();
    // 登陆远程计算机的远程,
    4 op.Username = "Domain\Domainuser"; 5 op.Password = "password"; 6 // 该处不能使用ip必须是"计算机名称.域名 ootcimv2" 7 ManagementScope scope = new ManagementScope(@"\Servername.Domain ootcimv2", op); 8 scope.Connect(); 9 ManagementPath path = new ManagementPath("Win32_Service"); 10 using(ManagementClass services = new ManagementClass(scope, path, null)) 11 { 12 foreach (ManagementObject service in services.GetInstances()) 13 { 14 Console.WriteLine("{0}:{1}",service.GetPropertyValue("Name").ToString(),service.GetPropertyValue("State").ToString()); 15 } 16 } 17 18 Console.ReadKey(); 19 }

     如何远程Stop/Start远程机子上的服务?

    在gfsoso上搜出别人总结的经验: http://www.gkspk.com/view/programming/working-with-windows-services-using-csharp-and-wmi/

    远程控制可以有以下几种方式:

    • WMI Queries via classes in the System.Management namespace,
    • Strongly-typed WMI proxy classes generated using MgmtClassGen.exe, and
    • The System.ServiceProcess.ServiceController class.

    WMI queries

    首先我们需要使用ConnectionOptions来连通远程机:

     1 ConnectionOptions options = new ConnectionOptions();
     2 
     3 // If we are connecting to a remote host and want to
     4 // connect as a different user, we need to set some options
     5 //options.Username = 
     6 //options.Password =
     7 //options.Authority = 
     8 //options.EnablePrivileges = 
     9 
    10 // If we are connecting to a remote host, we need to specify the hostname:
    11 //string providerPath = @"\Hostname
    ootCIMv2";
    12 string providerPath = @"rootCIMv2";
    13 
    14 ManagementScope scope = new ManagementScope(providerPath, options);
    15 scope.Connect();


    我们使用WMI支持一种查询方式叫做WQL,它的用法是类似于SQL。我们可以使用WQL去查询某台服务器的上的服务运行状态:

    ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Service WHERE Name LIKE 'SQL%'");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
    
    foreach (ManagementObject o in searcher.Get())
    {
        string name = o["Name"];
        ...
    }

    我们可以使用ManagementObject去对单个远程的WindowsService进行控制:比如停止服务(Invoke函数:StopService)或者启动服务(Invoke 函数:StartService);

    1 ManagementPath path = new ManagementPath("Win32_Service.Name='SomeWindowsService'");
    2 ManagementObject obj = new ManagementObject(scope, path, new ObjectGetOptions());
    3 ManagementBaseObject outParams = obj.InvokeMethod("StartService", (ManagementBaseObject)null, null);
    4 uint returnCode = System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value);

     上边这种方法是一种同步的方法,当然我们也可以使用异步接收InvokeMethod执行结果。

    1 ManagementOperationObserver observer = new ManagementOperationObserver();
    2 // The ObjectReadyHandler method will need a prototype of
    3 //    public void ObjectReadyHandler(object sender, ObjectReadyEventArgs e) { ... }
    4 observer.ObjectReady += ObjectReadyHandler;
    5 obj.InvokeMethod(observer, "StartService", new object[0]);

     ManagementOperationObserver有两个事件可以订约,你可以订约ObjectReady,也可以订约Completed事件。

    WMI proxy classes

    你可以使用.NET Framework包含的一个强类型WMI代理类生成工具,你可以是使用一下命令生成对类Win32_Service的代理类:

     1 MgmtClassGen.exe Win32_Service /L CS /O some.namespace /N rootcimv2 /P ServiceProxy.cs 

    执行这些代码后,你将得到一个ServiceProxy.cs文件,在使用该代理类的时候,你还需要结合ConnectionOptions使用:

    1 string condition = "Name LIKE 'SQL%'";
    2 ServiceProxy.ServiceCollection sc = ServiceProxy.GetInstances(scope, condition);
    3 foreach (ServiceProxy s in sc)
    4 {
    5     string name = s.Name;
    6     ...
    7     s.StartService();
    8 }

     Service Controller

    System.Management.dll下微软封装好了一个这样的类,该类也是我们大多数人对本地服务进行操作时,搜选方案,当时远程机也可以,但该类在操作远程机时,必须要启动你的软件以有权限操作其他机子的账户(比如:账户A在你的远程机上也有该账户,在远程机上该账户也有对WMI操作权限)。

    所以说,当在控制远程机上的服务时,使用该类的局限性很大,而且不可以切换用户。

    1 ServiceController controller = new ServiceController("servicename", "hostname");
    2 if (ServiceControllerStatus.Stopped == controller.Status)
    3 {
    4     controller.Start();
    5     // You can use the following line to wait for service to finish starting
    6     // you can supply a TimeSpan object to this method to timeout after that period.
    7     controller.WaitForStatus(ServiceControllerStatus.Running);
    8 }

    运行结果,果然不负众望。

    参考:

    1,)http://www.codeproject.com/Articles/36268/Monitor-and-Manage-Services-on-Remote-Machines

    2,)http://www.codeitive.com/0HJgVkjVeq/check-status-of-services-that-run-in-a-remote-computer-using-c.html

    3,)http://www.gkspk.com/view/programming/working-with-windows-services-using-csharp-and-wmi/

  • 相关阅读:
    C# 把类实例保存到文件里(类的序列化和反序列化)
    C# 枚举的初始化
    旋转 3d
    asp.net页面间传值方式
    sql获取当前时间
    SqlServer中循环和条件语句示例!
    SQL Server 代理(已禁用代理 XP)
    JQuery源码实现
    C#计算一段程序运行时间的三种方法
    java开发配套版本
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/4520023.html
Copyright © 2020-2023  润新知