當前位置:首頁>>開發(fā)編程>>VS.NET>>新聞內(nèi)容
使用C#控制遠程計算機的服務(wù)
作者:佚名 發(fā)布時間:2004-7-26 10:16:18 文章來源:西部E網(wǎng)

       在.net中提供了一些類來顯示和控制Windows系統(tǒng)上的服務(wù),并可以實現(xiàn)對遠程計算機服務(wù)服務(wù)的訪問,如System.ServiceProcess命名空間下面的ServiceController 類,System.Management下面的一些WMI操作的類。雖然用

ServiceController可以很方便的實現(xiàn)對服務(wù)的控制,而且很直觀、簡潔和容易理解。但是我認為他的功能同通過WMI來操作服務(wù)相比,那可能就有些單一了,并且對多個服務(wù)的操作可能就比較麻煩,也無法列出系統(tǒng)中的所有服務(wù)的具體數(shù)據(jù)。這里要講的就是如何使用System.Management組件來操作遠程和本地計算機上的服務(wù)。

        WMI作為Windows 2000操作系統(tǒng)的一部分提供了可伸縮的,可擴展的管理架構(gòu).公共信息模型(CIM)是由分布式管理任務(wù)標準協(xié)會(DMTF)設(shè)計的一種可擴展的、面向?qū)ο蟮募軜?gòu),用于管理系統(tǒng)、網(wǎng)絡(luò)、應(yīng)用程序、數(shù)據(jù)庫和設(shè)備。Windows管理規(guī)范也稱作CIM for Windows,提供了統(tǒng)一的訪問管理信息的方式。如果需要獲取詳細的WMI信息請讀者查閱MSDN。System.Management組件提供對大量管理信息和管理事件集合的訪問,這些信息和事件是與根據(jù) Windows 管理規(guī)范 (WMI) 結(jié)構(gòu)對系統(tǒng)、設(shè)備和應(yīng)用程序設(shè)置檢測點有關(guān)的。
       
  但是上面并不是我們最關(guān)心的,下面才是我們需要談的話題。

  毫無疑問,我們要引用System.Management.Dll程序集,并要使用System.Management命名空間下的類,如ManagementClass,ManagementObject等。下面用一個名為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;
              }
         }

         // 驗證是否能連接到遠程計算機
         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];
         }
         // 獲取所連接的計算機的所有服務(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;
         }
         // 獲取所連接的計算機的指定服務(wù)數(shù)據(jù)
         public string [,] GetServiceList(string serverName)
         {
              return GetServiceList(new string []{serverName});
         }
         // 獲取所連接的計算機的的指定服務(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中通過RemoteConnectValidate靜態(tài)方法來測試連接成功與否;另外提供了GetServiceValue方法和GetServiceList方法以及它的重載來獲取服務(wù)信息;后面的四個方法就是對服務(wù)的狀態(tài)控制了。
     下面建立一個簡單的窗口來使用它。
大致的界面如下:

通過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 "啟動":
                       string startRst = this.serviceManager.StartService(this.listViewService.SelectedItems[0].SubItems[0].Text);
                       if(startRst==null)
                            MessageBox.Show("操作成功,請點擊獲取刷新按鈕刷新結(jié)果!");
                       else
                            MessageBox.Show(startRst);
                       break;
                   case "暫停":
                       string startPause = this.serviceManager.PauseService(this.listViewService.SelectedItems[0].SubItems[0].Text);
                       if(startPause==null)
                            MessageBox.Show("操作成功,請點擊獲取刷新按鈕刷新結(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("操作成功,請點擊獲取刷新按鈕刷新結(jié)果!");
                       else
                            MessageBox.Show(startResume);
                       break;
                   case "停止":
                       string startStop = this.serviceManager.StopService(this.listViewService.SelectedItems[0].SubItems[0].Text);
                       if(startStop==null)
                            MessageBox.Show("操作成功,請點擊獲取刷新按鈕刷新結(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("連接到遠程計算機驗證錯誤.");
                            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地址");
         }
    }
}
     說明,其實一個服務(wù)的屬性和方法除了上面這幾個還有很多,我們可以通過實例化ManagementClass類,使用它的Properties屬性和Methods屬性列出所有的屬性和方法。上面的Win32ServiceManager中生成的每個服務(wù)實例都是ManagementObejct類型的,其實還有一種強類型的類,可以通過編程和工具來生成。
     總結(jié),通過引用System.Management命名空間,上面簡單的實現(xiàn)了通過訪問\root\cimv2:Win32_Service名稱空間對服務(wù)進行顯示和操作。此外,我們還可以通過訪問其他名稱空間來訪問計算機的一些硬件信息,軟件信息以及網(wǎng)絡(luò)等,有興趣的讀者可以研究一下。


最新更新
·C#中使用Split分隔字符串的技
·VS2008開發(fā)中Windows Mobile
·PC機和移動設(shè)備上絕對路徑的
·C#程序加殼的方法(使用Sixx
·當前上下文中不存在名稱Conf
·請插入磁盤:Visual Studio 2
·用VS.NET讀取Flash格式文件信
·在ASP.NET中使用AJAX的簡單方
·VS.NET 2005中常用的一些代碼
·安裝VS.NET 2005 SP1補丁全攻
相關(guān)信息
·C#中使用Split分隔字符串的技巧
·PC機和移動設(shè)備上絕對路徑的獲取(C#)
·C#程序加殼的方法(使用Sixxpack)
·當前上下文中不存在名稱ConfigurationManager的解決方法
·C#的支付寶Payto接口代碼
·C#實現(xiàn)窗口最小化到系統(tǒng)托盤
·解密QQ的MsgEx.db消息文件格式
·QQ的TEA填充算法C#實現(xiàn)
·C#用Guid獲取不規(guī)則的唯一值(標識)
·基于Windows Mobile 5.0的掌上天氣預(yù)報設(shè)計
畫心
愚愛
偏愛
火苗
白狐
畫沙
犯錯
歌曲
傳奇
稻香
小酒窩
獅子座
小情歌
全是愛
棉花糖
海豚音
我相信
甩蔥歌
這叫愛
shero
走天涯
琉璃月
Nobody
我愛他
套馬桿
愛是你我
最后一次
少女時代
灰色頭像
斷橋殘雪
美了美了
狼的誘惑
我很快樂
星月神話
心痛2009
愛丫愛丫
半城煙沙
旗開得勝
郎的誘惑
愛情買賣
2010等你來
我叫小沈陽
i miss you
姑娘我愛你
我們都一樣
其實很寂寞
我愛雨夜花
變心的玫瑰
犀利哥之歌
你是我的眼
你是我的OK繃
貝多芬的悲傷
哥只是個傳說
丟了幸福的豬
找個人來愛我
要嫁就嫁灰太狼
如果這就是愛情
我們沒有在一起
寂寞在唱什么歌
斯琴高麗的傷心
別在我離開之前離開
不是因為寂寞才想你
愛上你等于愛上了錯
在心里從此永遠有個你
一個人的寂寞兩個人的錯