在.net中提供了一些類來(lái)顯示和控制windows系統(tǒng)上的服務(wù),并可以實(shí)現(xiàn)對(duì)遠(yuǎn)程計(jì)算機(jī)服務(wù)服務(wù)的訪問(wèn),如system.serviceprocess命名空間下面的servicecontroller 類,system.management下面的一些wmi操作的類。雖然用servicecontroller可以很方便的實(shí)現(xiàn)對(duì)服務(wù)的控制,而且很直觀、簡(jiǎn)潔和容易理解。但是我認(rèn)為他的功能同通過(guò)wmi來(lái)操作服務(wù)相比,那可能就有些單一了,并且對(duì)多個(gè)服務(wù)的操作可能就比較麻煩,也無(wú)法列出系統(tǒng)中的所有服務(wù)的具體數(shù)據(jù)。這里要講的就是如何使用system.management組件來(lái)操作遠(yuǎn)程和本地計(jì)算機(jī)上的服務(wù)。
wmi作為windows 2000操作系統(tǒng)的一部分提供了可伸縮的,可擴(kuò)展的管理架構(gòu).公共信息模型(cim)是由分布式管理任務(wù)標(biāo)準(zhǔn)協(xié)會(huì)(dmtf)設(shè)計(jì)的一種可擴(kuò)展的、面向?qū)ο蟮募軜?gòu),用于管理系統(tǒng)、網(wǎng)絡(luò)、應(yīng)用程序、數(shù)據(jù)庫(kù)和設(shè)備。windows管理規(guī)范也稱作cim for windows,提供了統(tǒng)一的訪問(wèn)管理信息的方式。如果需要獲取詳細(xì)的wmi信息請(qǐng)讀者查閱msdn。system.management組件提供對(duì)大量管理信息和管理事件集合的訪問(wèn),這些信息和事件是與根據(jù) windows 管理規(guī)范 (wmi) 結(jié)構(gòu)對(duì)系統(tǒng)、設(shè)備和應(yīng)用程序設(shè)置檢測(cè)點(diǎn)有關(guān)的。
但是上面并不是我們最關(guān)心的,下面才是我們需要談的話題。
毫無(wú)疑問(wèn),我們要引用system.management.dll程序集,并要使用system.management命名空間下的類,如managementclass,managementobject等。下面用一個(gè)名為win32servicemanager的類把服務(wù)的一些相關(guān)操作包裝了一下,代碼如下:
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;
}
}
// 驗(yàn)證是否能連接到遠(yuǎn)程計(jì)算機(jī)
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;
}
// 獲取指定服務(wù)屬性的值
public object getservicevalue(string servicename,string propertyname)
{
managementobject mo = this.managementclass.createinstance();
mo.path = new managementpath(this.strpath+".name=/""+servicename+"/"");
return mo[propertyname];
}
// 獲取所連接的計(jì)算機(jī)的所有服務(wù)數(shù)據(jù)
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;
}
// 獲取所連接的計(jì)算機(jī)的指定服務(wù)數(shù)據(jù)
public string [,] getservicelist(string servername)
{
return getservicelist(new string []{servername});
}
// 獲取所連接的計(jì)算機(jī)的的指定服務(wù)數(shù)據(jù)
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;
}
// 停止指定的服務(wù)
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;
}
// 暫停指定的服務(wù)
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;
}
// 恢復(fù)指定的服務(wù)
public string resumeservice(string servicename)
{
string strrst = null;
managementobject mo = this.managementclass.createinstance();
mo.path = new managementpath(this.strpath+".name=/""+servicename+"/"");
try
{
//判斷是否可以恢復(fù)
if((bool)mo["acceptpause"]&&(string)mo["state"]=="paused")
mo.invokemethod("resumeservice",null);
}
catch(managementexception e)
{
strrst =e.message;
}
return strrst;
}
// 停止指定的服務(wù)
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中通過(guò)remoteconnectvalidate靜態(tài)方法來(lái)測(cè)試連接成功與否;另外提供了getservicevalue方法和getservicelist方法以及它的重載來(lái)獲取服務(wù)信息;后面的四個(gè)方法就是對(duì)服務(wù)的狀態(tài)控制了。
下面建立一個(gè)簡(jiǎn)單的窗口來(lái)使用它。
大致的界面如下:
通過(guò)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());
}
//修改服務(wù)狀態(tài)
private void buttonchangestate_click(object sender, system.eventargs e)
{
switch(((button)sender).text)
{
case "啟動(dòng)":
string startrst = this.servicemanager.startservice(this.listviewservice.selecteditems[0].subitems[0].text);
if(startrst==null)
messagebox.show("操作成功,請(qǐng)點(diǎn)擊獲取刷新按鈕刷新結(jié)果!");
else
messagebox.show(startrst);
break;
case "暫停":
string startpause = this.servicemanager.pauseservice(this.listviewservice.selecteditems[0].subitems[0].text);
if(startpause==null)
messagebox.show("操作成功,請(qǐng)點(diǎn)擊獲取刷新按鈕刷新結(jié)果!");
else
messagebox.show(startpause);
break;
case "繼續(xù)":
string startresume = this.servicemanager.resumeservice(this.listviewservice.selecteditems[0].subitems[0].text);
if(startresume==null)
messagebox.show("操作成功,請(qǐng)點(diǎn)擊獲取刷新按鈕刷新結(jié)果!");
else
messagebox.show(startresume);
break;
case "停止":
string startstop = this.servicemanager.stopservice(this.listviewservice.selecteditems[0].subitems[0].text);
if(startstop==null)
messagebox.show("操作成功,請(qǐng)點(diǎn)擊獲取刷新按鈕刷新結(jié)果!");
else
messagebox.show(startstop);
break;
}
}
//獲取和刷新數(shù)據(jù)
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("連接到遠(yuǎn)程計(jì)算機(jī)驗(yàn)證錯(cuò)誤.");
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("請(qǐng)輸入計(jì)算機(jī)名或ip地址");
}
}
}
說(shuō)明,其實(shí)一個(gè)服務(wù)的屬性和方法除了上面這幾個(gè)還有很多,我們可以通過(guò)實(shí)例化managementclass類,使用它的properties屬性和methods屬性列出所有的屬性和方法。上面的win32servicemanager中生成的每個(gè)服務(wù)實(shí)例都是managementobejct類型的,其實(shí)還有一種強(qiáng)類型的類,可以通過(guò)編程和工具來(lái)生成。
總結(jié),通過(guò)引用system.management命名空間,上面簡(jiǎn)單的實(shí)現(xiàn)了通過(guò)訪問(wèn)/root/cimv2:win32_service名稱空間對(duì)服務(wù)進(jìn)行顯示和操作。此外,我們還可以通過(guò)訪問(wèn)其他名稱空間來(lái)訪問(wèn)計(jì)算機(jī)的一些硬件信息,軟件信息以及網(wǎng)絡(luò)等,有興趣的讀者可以研究一下。