C#高级编程:ServiceController类

今天在做一个后台服务的自动安装和卸载的小程序时,接触到了这个类

要使用这个System.ServiceProcess.ServiceController类,这就要是用到System.Service Process.dll

先来了解下这个类,主要是用来检测系统后台服务的

1. 服务的监视

使用ServiceController类,可以获取每一个服务的信息。ServiceController类的下列属性可以用于获取服务的信息,如表32-4所示。

  32-4

 

 

CanPauseAndContinue

如果暂停和继续服务的请求可以发送给服务,则这个属性返回true

CanShutdown

如果服务有系统关闭的处理程序,则它的值为true

CanStop

如果服务是可以停止的,则它的值为true

DependentServices

它返回一个依存服务的集合。如果服务停止,则所有依存的服务都预先停止

ServicesDependentOn

这个属性返回这个服务所依存的服务集合

DisplayName

这个属性返回服务应该显示的名称

MachineName

这个属性返回运行服务的机器名

ServiceName

服务的名称

ServiceType

指定服务的类型。服务可以运行在共享的进程中。在共享的进程中,多个服务使用同一进程(Win32ShareProcess),此外,服务也可以运行在只包含一个服务的进程(Win32OwnProcess)中。如果服务可以与桌面交互,则类型就是InteractiveProcess

Status

这个属性返回服务的状态。状态可以是正在运行、停止、暂停或某些中间模式(如启动待决、停止待决)等。状态值在ServiceControllerStatus枚举中定义

CanPauseAndContinueCanStop用于启用和禁用PauseContinueStop按钮。

服务的状态和类型的设置就比较麻烦了,原因是ServiceController类返回的是数字,而显示时却要使用字符串代替数字。为了把状态和类型显示为字符串,需要使用两个帮助函数SetServiceStatus()GetServiceTypeName()

  protected string GetServiceTypeName(ServiceType type)
{
string serviceType = "";
if ((type & ServiceType.InteractiveProcess) != 0)
{
serviceType
= "Interactive ";
type
-= ServiceType.InteractiveProcess;
}
switch (type)
{
case ServiceType.Adapter:
serviceType
+= "Adapter";
break;
case ServiceType.FileSystemDriver:
case ServiceType.KernelDriver:
case ServiceType.RecognizerDriver:
serviceType
+= "Driver";
break;
case ServiceType.Win32OwnProcess:
serviceType
+= "Win32 Service Process";
break;
case ServiceType.Win32ShareProcess:
serviceType
+= "Win32 Shared Process";
break;
default:
serviceType
+= "unknown type " + type.ToString();
break;
}
return serviceType;
}

  方法SetServiceStatus()在文本框textServiceStatus中设置服务的当前状态。根据服务的状态,可以启用或禁用StartStopPauseContinue按钮。

protected void SetServiceStatus(ServiceController controller)
{
buttonStart.Enabled
= true;
buttonStop.Enabled
= true;
buttonPause.Enabled
= true;
buttonContinue.Enabled
= true;
if (!controller.CanPauseAndContinue)
{
buttonPause.Enabled
= false;
buttonContinue.Enabled
= false;
}
if (!controller.CanStop)
{
buttonStop.Enabled
= false;
}
ServiceControllerStatus status
= controller.Status;
switch (status)
{
case ServiceControllerStatus.ContinuePending:
textBoxServiceStatus.Text
= "Continue Pending";
buttonContinue.Enabled
= false;
break;
case ServiceControllerStatus.Paused:
textBoxServiceStatus.Text
= "Paused";
buttonPause.Enabled
= false;
buttonStart.Enabled
= false;
break;
case ServiceControllerStatus.PausePending:
textBoxServiceStatus.Text
= "Pause Pending";
buttonPause.Enabled
= false;
buttonStart.Enabled
= false;
break;
case ServiceControllerStatus.StartPending:
textBoxServiceStatus.Text
= "Start Pending";
buttonStart.Enabled
= false;
break;
case ServiceControllerStatus.Running:
textBoxServiceStatus.Text
= "Running";
buttonStart.Enabled
= false;
buttonContinue.Enabled
= false;
break;
case ServiceControllerStatus.Stopped:
textBoxServiceStatus.Text
= "Stopped";
buttonStop.Enabled
= false;
break;
case ServiceControllerStatus.StopPending:
textBoxServiceStatus.Text
= "Stop Pending";
buttonStop.Enabled
= false;
break;
default:
textServiceStatus.Text
= "Unknown status";
break;

}

  OnSelectedIndexChanged ()是列表框事件SelectedIndexChanged的处理程序。当用户选择列表框事件中的一个服务时,就会调用这个处理程序。在OnSelectedIndexChanged()中,直接使用ServiceController类的属性来设置服务的显示名称和名称。调用帮助方法GetServiceTypeName()来设置服务类型。

  protected void OnSelectedIndexChanged (object sender,
System.EventArgs e)
{
ServiceController controller
=
(ServiceController)listBoxServices.SelectedItem;
textBoxDisplayName.Text
= controller.DisplayName;
textBoxServiceType.Text
= GetServiceTypeName(controller.ServiceType);
textBoxServiceName.Text
= controller.ServiceName;
SetServiceStatus(controller);
}

  

2. 服务的控制

使用ServiceController类,也可以把控制请求发送给服务,该类的方法如表32-5所示。

  32-5

 

 

Start()

Start() 告诉SCM应启动服务。在我们的服务程序中,调用了OnStart()

Stop()

如果CanStop属性在服务类中的值是true,则在SCM的帮助下,Stop()调用服务程序中的OnStop()

Pause()

如果CanPauseAndContinue属性的值是true,则Pause() 调用OnPause()

Continue()

如果CanPauseAndContinue属性的值是true,则Continue调用OnContinue()

ExecuteCommand()

使用 ExecuteCommand()可以把定制的命令发送给服务

下面的代码就是控制服务的代码。因为启动、停止、挂起和暂停服务的代码是相似的,所以仅为这4个按钮使用一个处理程序:

  protected void buttonCommand_Click(object sender, System.EventArgs e)
{
Cursor.Current
= Cursors.WaitCursor;
ServiceController controller
=
(ServiceController)listBoxServices.SelectedItem;
if (sender == this.buttonStart)
{
controller.Start();
controller.WaitForStatus(ServiceControllerStatus.Running);
}
else if (sender == this.buttonStop)
{
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped);
}
else if (sender == this.buttonPause)
{
controller.Pause();
controller.WaitForStatus(ServiceControllerStatus.Paused);
}
else if (sender == this.buttonContinue)
{
controller.Continue();
controller.WaitForStatus(ServiceControllerStatus.Running);
}
int index =listBoxServices.SelectedIndex;
RefreshServiceList();
listBoxServices.SelectedIndex
= index;
Cursor.Current
= Cursors.Default;
}

protected void buttonExit_Click(object sender, System.EventArgs e)
{
Application.Exit();
}
protected void buttonRefresh_Click(object sender, System.EventArgs e)
{
RefreshServiceList();
}

  总结一下,这个类很重要也很常用。它负责对服务的查找和管理

   下面是之前写的两个小方法,负责监听某项服务是否已存在,和是否在运行



View Code
     private bool ServiceIsExisted(string serviceName)//用来判断服务中是否已经启动了MoniterScadaqzj
{
System.ServiceProcess.ServiceController[] services
= System.ServiceProcess.ServiceController.GetServices();
foreach (System.ServiceProcess.ServiceController s in services)
{
if (s.ServiceName == serviceName)
{
return true;
}
}
return false;

}
private void ServiceIsRun(string ServerName,bool status)//判断进程是不是运行着 ,如果是运行着 就关掉
{
//true 是运行着要关闭,false是没有运行要运行
System.ServiceProcess.ServiceController[] services = System.ServiceProcess.ServiceController.GetServices();
foreach (System.ServiceProcess.ServiceController s in services)
{
if (s.ServiceName == ServerName)
{
if(status==true) //想让他关闭
{
if ((s.Status == ServiceControllerStatus.Running))
{
s.Stop();
}
}
else //想让他运行
{
s.Start();
}
}
}

}
posted @ 2011-09-06 09:19  Tammie-锴  阅读(3194)  评论(0编辑  收藏  举报