欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#中控制远程计算机的服务的方法

程序员文章站 2023-11-14 14:09:58
在.net中提供了一些类来显示和控制windows系统上的服务,并可以实现对远程计算机服务服务的访问,如system.serviceprocess命名空间下面的servic...
在.net中提供了一些类来显示和控制windows系统上的服务,并可以实现对远程计算机服务服务的访问,如system.serviceprocess命名空间下面的servicecontroller 类,system.management下面的一些wmi操作的类。虽然用servicecontroller可以很方便的实现对服务的控制,而且很直观、简洁和容易理解。但是我认为他的功能同通过wmi来操作服务相比,那可能就有些单一了,并且对多个服务的操作可能就比较麻烦,也无法列出系统中的所有服务的具体数据。这里要讲的就是如何使用system.management组件来操作远程和本地计算机上的服务。 
wmi作为windows 2000操作系统的一部分提供了可伸缩的,可扩展的管理架构.公共信息模型(cim)是由分布式管理任务标准协会(dmtf)设计的一种可扩展的、面向对象的架构,用于管理系统、网络、应用程序、数据库和设备。windows管理规范也称作cim for windows,提供了统一的访问管理信息的方式。如果需要获取详细的wmi信息请读者查阅msdn。system.management组件提供对大量管理信息和管理事件集合的访问,这些信息和事件是与根据 windows 管理规范 (wmi) 结构对系统、设备和应用程序设置检测点有关的。 
但是上面并不是我们最关心的,下面才是我们需要谈的话题。 
毫无疑问,我们要引用system.management.dll程序集,并要使用system.management命名空间下的类,如managementclass,managementobject等。下面用一个名为win32servicemanager的类把服务的一些相关操作包装了一下,代码如下: 
using system; 
using system.management; 
namespace zz.wmi 

public class win32servicemanager 

private string strpath; 
private managementclass managementclass; 
public win32servicemanager():this(".",null,null) 


public win32servicemanager(string host,string username,string password) 

this.strpath = "\\\\"+host+"\\root\\cimv2:win32_service"; 
this.managementclass = new managementclass(strpath); 
if(username!=null&&username.length>0) 

connectionoptions connectionoptions = new connectionoptions(); 
connectionoptions.username = username; 
connectionoptions.password = password; 
managementscope managementscope = new managementscope( "\\\\" +host+ "\\root\\cimv2",connectionoptions) ; 
this.managementclass.scope = managementscope; 


// 验证是否能连接到远程计算机 
public static bool remoteconnectvalidate(string host,string username,string password) 

connectionoptions connectionoptions = new connectionoptions(); 
connectionoptions.username = username; 
connectionoptions.password = password; 
managementscope managementscope = new managementscope( "\\\\" +host+ "\\root\\cimv2",connectionoptions) ; 
try 

managementscope.connect(); 

catch 


return managementscope.isconnected; 

// 获取指定服务属性的值 
public object getservicevalue(string servicename,string propertyname) 

managementobject mo = this.managementclass.createinstance(); 
mo.path = new managementpath(this.strpath+".name=\""+servicename+"\""); 
return mo[propertyname]; 

// 获取所连接的计算机的所有服务数据 
public string [,] getservicelist() 

string [,] services = new string [this.managementclass.getinstances().count,4]; 
int i = 0; 
foreach(managementobject mo in this.managementclass.getinstances()) 

services[i,0] = (string)mo["name"]; 
services[i,1] = (string)mo["displayname"]; 
services[i,2] = (string)mo["state"]; 
services[i,3] = (string)mo["startmode"]; 
i++; 

return services; 

// 获取所连接的计算机的指定服务数据 
public string [,] getservicelist(string servername) 

return getservicelist(new string []{servername}); 

// 获取所连接的计算机的的指定服务数据 
public string [,] getservicelist(string [] servernames) 

string [,] services = new string [servernames.length,4]; 
managementobject mo = this.managementclass.createinstance(); 
for(int i = 0;i<servernames.length;i++) 

mo.path = new managementpath(this.strpath+".name=\""+servernames[i]+"\""); 
services[i,0] = (string)mo["name"]; 
services[i,1] = (string)mo["displayname"]; 
services[i,2] = (string)mo["state"]; 
services[i,3] = (string)mo["startmode"]; 

return services; 

// 停止指定的服务 
public string startservice(string servicename) 

string strrst = null; 
managementobject mo = this.managementclass.createinstance(); 
mo.path = new managementpath(this.strpath+".name=\""+servicename+"\""); 
try 

if((string)mo["state"]=="stopped")//!(bool)mo["acceptstop"] 
mo.invokemethod("startservice",null); 

catch(managementexception e) 

strrst =e.message; 

return strrst; 

// 暂停指定的服务 
public string pauseservice(string servicename) 

string strrst = null; 
managementobject mo = this.managementclass.createinstance(); 
mo.path = new managementpath(this.strpath+".name=\""+servicename+"\""); 
try 

//判断是否可以暂停 
if((bool)mo["acceptpause"]&&(string)mo["state"]=="running") 
mo.invokemethod("pauseservice",null); 

catch(managementexception e) 

strrst =e.message; 

return strrst; 

// 恢复指定的服务 
public string resumeservice(string servicename) 

string strrst = null; 
managementobject mo = this.managementclass.createinstance(); 
mo.path = new managementpath(this.strpath+".name=\""+servicename+"\""); 
try 

//判断是否可以恢复 
if((bool)mo["acceptpause"]&&(string)mo["state"]=="paused") 
mo.invokemethod("resumeservice",null); 

catch(managementexception e) 

strrst =e.message; 

return strrst; 

// 停止指定的服务 
public string stopservice(string servicename) 

string strrst = null; 
managementobject mo = this.managementclass.createinstance(); 
mo.path = new managementpath(this.strpath+".name=\""+servicename+"\""); 
try 

//判断是否可以停止 
if((bool)mo["acceptstop"])//(string)mo["state"]=="running" 
mo.invokemethod("stopservice",null); 

catch(managementexception e) 

strrst =e.message; 

return strrst; 



在win32servicemanager中通过remoteconnectvalidate静态方法来测试连接成功与否;另外提供了getservicevalue方法和getservicelist方法以及它的重载来获取服务信息;后面的四个方法就是对服务的状态控制了。 
下面建立一个简单的窗口来使用它。 
大致的界面如下: 

通过vs.net 2003可以很快做出上面的窗体,下面列出了一些增加的代码: 


using zz.wmi; 
namespace zzform 

public class form1 : system.windows.forms.form 

//…… 
private win32servicemanager servicemanager; 
public form1() 

initializecomponent(); 
this.servicemanager = null; 

//…… 
[stathread] 
static void main() 

application.run(new form1()); 

//修改服务状态 
private void buttonchangestate_click(object sender, system.eventargs e) 

switch(((button)sender).text) 

case "启动": 
string startrst = this.servicemanager.startservice(this.listviewservice.selecteditems[0].subitems[0].text); 
if(startrst==null) 
messagebox.show("操作成功,请点击获取刷新按钮刷新结果!"); 
else 
messagebox.show(startrst); 
break; 
case "暂停": 
string startpause = this.servicemanager.pauseservice(this.listviewservice.selecteditems[0].subitems[0].text); 
if(startpause==null) 
messagebox.show("操作成功,请点击获取刷新按钮刷新结果!"); 
else 
messagebox.show(startpause); 
break; 
case "继续": 
string startresume = this.servicemanager.resumeservice(this.listviewservice.selecteditems[0].subitems[0].text); 
if(startresume==null) 
messagebox.show("操作成功,请点击获取刷新按钮刷新结果!"); 
else 
messagebox.show(startresume); 
break; 
case "停止": 
string startstop = this.servicemanager.stopservice(this.listviewservice.selecteditems[0].subitems[0].text); 
if(startstop==null) 
messagebox.show("操作成功,请点击获取刷新按钮刷新结果!"); 
else 
messagebox.show(startstop); 
break; 


//获取和刷新数据 
private void buttonloadrefresh_click(object sender, system.eventargs e) 

if(this.textboxhost.text.trim().length>0) 

if(this.textboxhost.text.trim()==".") 

this.servicemanager = new win32servicemanager(); 

else 

if(win32servicemanager.remoteconnectvalidate(this.textboxhost.text.trim(),this.textboxname.text.trim(),this.textboxpassword.text.trim())) 

this.servicemanager = new win32servicemanager(this.textboxhost.text.trim(),this.textboxname.text.trim(),this.textboxpassword.text.trim()); 

else 

messagebox.show("连接到远程计算机验证错误."); 
return; 


string [,] services = servicemanager.getservicelist(); 
this.listviewservice.beginupdate(); 
this.listviewservice.items.clear(); 
for(int i=0;i<services.getlength(0);i++) 

listviewitem item = new listviewitem(new string[]{services[i,0],services[i,1],services[i,2],services[i,3]}); 
this.listviewservice.items.add(item); 

this.listviewservice.endupdate(); 

else 
messagebox.show("请输入计算机名或ip地址"); 



说明,其实一个服务的属性和方法除了上面这几个还有很多,我们可以通过实例化managementclass类,使用它的properties属性和methods属性列出所有的属性和方法。上面的win32servicemanager中生成的每个服务实例都是managementobejct类型的,其实还有一种强类型的类,可以通过编程和工具来生成。 
总结,通过引用system.management命名空间,上面简单的实现了通过访问\root\cimv2:win32_service名称空间对服务进行显示和操作。此外,我们还可以通过访问其他名称空间来访问计算机的一些硬件信息,软件信息以及网络等,有兴趣的读者可以研究一下。