static void Main(string[] args)
{
ConnectionOptions op = new ConnectionOptions();
// 登陆远程计算机的远程,
op.Username = "Domain\\Domainuser";
op.Password = "password";
// 该处不能使用ip必须是"计算机名称.域名\root\cimv2"
ManagementScope scope = new ManagementScope(@"\\Servername.Domain\root\cimv2", op);
scope.Connect();
ManagementPath path = new ManagementPath("Win32_Service");
using(ManagementClass services = new ManagementClass(scope, path, null))
{
foreach (ManagementObject service in services.GetInstances())
{
Console.WriteLine("{0}:{1}",service.GetPropertyValue("Name").ToString(),service.GetPropertyValue("State").ToString());
}
} Console.ReadKey();
}
如何远程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来连通远程机:
ConnectionOptions options = new ConnectionOptions(); // If we are connecting to a remote host and want to
// connect as a different user, we need to set some options
//options.Username =
//options.Password =
//options.Authority =
//options.EnablePrivileges = // If we are connecting to a remote host, we need to specify the hostname:
//string providerPath = @"\\Hostname\root\CIMv2";
string providerPath = @"root\CIMv2"; ManagementScope scope = new ManagementScope(providerPath, options);
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);
ManagementPath path = new ManagementPath("Win32_Service.Name='SomeWindowsService'");
ManagementObject obj = new ManagementObject(scope, path, new ObjectGetOptions());
ManagementBaseObject outParams = obj.InvokeMethod("StartService", (ManagementBaseObject)null, null);
uint returnCode = System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value);
上边这种方法是一种同步的方法,当然我们也可以使用异步接收InvokeMethod执行结果。
ManagementOperationObserver observer = new ManagementOperationObserver();
// The ObjectReadyHandler method will need a prototype of
// public void ObjectReadyHandler(object sender, ObjectReadyEventArgs e) { ... }
observer.ObjectReady += ObjectReadyHandler;
obj.InvokeMethod(observer, "StartService", new object[]);
ManagementOperationObserver有两个事件可以订约,你可以订约ObjectReady,也可以订约Completed事件。
WMI proxy classes
你可以使用.NET Framework包含的一个强类型WMI代理类生成工具,你可以是使用一下命令生成对类Win32_Service
的代理类:
MgmtClassGen.exe Win32_Service /L CS /O some.namespace /N root\cimv2 /P ServiceProxy.cs
执行这些代码后,你将得到一个ServiceProxy.cs文件,在使用该代理类的时候,你还需要结合ConnectionOptions使用:
string condition = "Name LIKE 'SQL%'";
ServiceProxy.ServiceCollection sc = ServiceProxy.GetInstances(scope, condition);
foreach (ServiceProxy s in sc)
{
string name = s.Name;
...
s.StartService();
}
Service Controller
System.Management.dll下微软封装好了一个这样的类,该类也是我们大多数人对本地服务进行操作时,搜选方案,当时远程机也可以,但该类在操作远程机时,必须要启动你的软件以有权限操作其他机子的账户(比如:账户A在你的远程机上也有该账户,在远程机上该账户也有对WMI操作权限)。
所以说,当在控制远程机上的服务时,使用该类的局限性很大,而且不可以切换用户。
ServiceController controller = new ServiceController("servicename", "hostname");
if (ServiceControllerStatus.Stopped == controller.Status)
{
controller.Start();
// You can use the following line to wait for service to finish starting
// you can supply a TimeSpan object to this method to timeout after that period.
controller.WaitForStatus(ServiceControllerStatus.Running);
}
运行结果,果然不负众望。
参考:
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/