首页 > 开发 > 综合 > 正文

使用C#控制远程计算机的服务

2024-07-21 02:18:36
字体:
来源:转载
供稿:网友
在.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名称空间对服务进行显示和操作。此外,我们还可以通过访问其他名称空间来访问计算机的一些硬件信息,软件信息以及网络等,有兴趣的读者可以研究一下。



发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表