当前位置:首页>>开发编程>>VS.NET>>新闻内容
使用C#控制远程计算机的服务
作者:佚名 发布时间:2004-7-26 10:16:18 文章来源:西部E网

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


最新更新
·C#中使用Split分隔字符串的技
·VS2008开发中Windows Mobile
·PC机和移动设备上绝对路径的
·C#程序加壳的方法(使用Sixx
·当前上下文中不存在名称Conf
·请插入磁盘:Visual Studio 2
·用VS.NET读取Flash格式文件信
·在ASP.NET中使用AJAX的简单方
·VS.NET 2005中常用的一些代码
·安装VS.NET 2005 SP1补丁全攻
相关信息
·C#中使用Split分隔字符串的技巧
·PC机和移动设备上绝对路径的获取(C#)
·C#程序加壳的方法(使用Sixxpack)
·当前上下文中不存在名称ConfigurationManager的解决方法
·C#的支付宝Payto接口代码
·C#实现窗口最小化到系统托盘
·解密QQ的MsgEx.db消息文件格式
·QQ的TEA填充算法C#实现
·C#用Guid获取不规则的唯一值(标识)
·基于Windows Mobile 5.0的掌上天气预报设计
画心
愚爱
偏爱
火苗
白狐
画沙
犯错
歌曲
传奇
稻香
小酒窝
狮子座
小情歌
全是爱
棉花糖
海豚音
我相信
甩葱歌
这叫爱
shero
走天涯
琉璃月
Nobody
我爱他
套马杆
爱是你我
最后一次
少女时代
灰色头像
断桥残雪
美了美了
狼的诱惑
我很快乐
星月神话
心痛2009
爱丫爱丫
半城烟沙
旗开得胜
郎的诱惑
爱情买卖
2010等你来
我叫小沈阳
i miss you
姑娘我爱你
我们都一样
其实很寂寞
我爱雨夜花
变心的玫瑰
犀利哥之歌
你是我的眼
你是我的OK绷
贝多芬的悲伤
哥只是个传说
丢了幸福的猪
找个人来爱我
要嫁就嫁灰太狼
如果这就是爱情
我们没有在一起
寂寞在唱什么歌
斯琴高丽的伤心
别在我离开之前离开
不是因为寂寞才想你
爱上你等于爱上了错
在心里从此永远有个你
一个人的寂寞两个人的错