首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
coofucoo (105)
Drate (69)
lphpc (30)
smallnest (61)
iiprogram (64)
downmoon (32)
danny_xcz (49)
btbtd (81)
qingrun (66)
tyrone1979 (21)
CSDN - 文档中心 - .NET 阅读:7030   评论: 28    参与评论
标题   使用C#控制远程计算机的服务     选择自 zhzuo 的 Blog
关键字   wmi 服务 远程
出处  
使用C#控制远程计算机的服务
 
        在.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名称空间对服务进行显示和操作。此外,我们还可以通过访问其他名称空间来访问计算机的一些硬件信息,软件信息以及网络等,有兴趣的读者可以研究一下。

相关文章
对该文的评论
CSDN 网友 ( 2005-08-31)
无法使用的代码
CSDN 网友 ( 2004-08-30)
我不知道你的listview怎么看起来像个datagrid,能给我一份吗。
非常感谢!btut2004@yahoo.com.cn
CSDN 网友 ( 2004-07-12)
如果在window应用程序环境下,public Win32ServiceManager():this(".",null,null)是可以的,目前我在ASP.NET下就出现“访问遭到拒绝”的异常,如果用帐号和密码构造的话,就出现“无法为本地连结使用用户凭证 ”,请问高手怎么解决?谢谢!
whatcantuse ( 2004-04-11)
可以给我一个吗
letiantxf@163.com
gongjunheng ( 2004-04-05)
gong_jun_heng@msn.com
谢了