-
C#教程之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名称空间对服务进行显示和操作。此外,我们还可以通过访问其他名称空间来访问计算机的一些硬件信息,软件信息以及网络等,有兴趣的读者可以研究一下。
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名称空间对服务进行显示和操作。此外,我们还可以通过访问其他名称空间来访问计算机的一些硬件信息,软件信息以及网络等,有兴趣的读者可以研究一下。
最新更新
Objective-C语法之代码块(block)的使用
VB.NET eBook
Add-in and Automation Development In VB.NET 2003 (F
Add-in and Automation Development In VB.NET 2003 (8
Add-in and Automation Development in VB.NET 2003 (6
Add-in and Automation Development In VB.NET 2003 (5
AddIn Automation Development In VB.NET 2003 (4)
AddIn And Automation Development In VB.NET 2003 (2)
Addin and Automation Development In VB.NET 2003 (3)
AddIn And Automation Development In VB.NET 2003 (1)
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
武装你的WEBAPI-OData入门
武装你的WEBAPI-OData便捷查询
武装你的WEBAPI-OData分页查询
武装你的WEBAPI-OData资源更新Delta
5. 武装你的WEBAPI-OData使用Endpoint 05-09
武装你的WEBAPI-OData之API版本管理
武装你的WEBAPI-OData常见问题
武装你的WEBAPI-OData聚合查询
OData WebAPI实践-OData与EDM
OData WebAPI实践-Non-EDM模式