ServiceController类

下面创建一个小的Windows应用程序,该应用程序使用ServiceController类监视和控制Windows服务。

创建一个Windows窗体应用程序,这个应用程序的用户界面包含一个显示所有服务的列表框、4个文本框(分别用于显示服务的显示名称、状态、类型和名称),以及4个发送控制事件的按钮,如图32-18所示。

  32-18

这里使用了System.ServiceProcess.ServiceController类,因此必须引用System.Service Process.dll

这里还执行了RefreshServiceList()方法,用下面的代码在列表框中列出所有的服务。这个方法是在ServiceControlForm类的构造函数中调用的。该方法用所有服务的显示名称填写listboxGetServics()ServiceController类的一个静态方法,它返回一个代表所有Windows服务的ServiceController数组。ServiceController类也有一个静态的方法GetDevices(),它返回一个代表所有设备驱动器的ServiceController数组。

ServiceController. GetServics()绑定到ListBox上,填充列表框:

  private System.ServiceProcess.ServiceController[] services;

 

  public ServiceControlForm()

  {

//

// Required for Windows Form Designer support

//

 

InitializeComponent();

   RefreshServiceList();

  }

  protected void RefreshServiceList()

  {

services = ServiceController.GetServices();

listBoxServices.DisplayMember = "DisplayName";

listBoxServices.DataSource = services;

  }

现在,所有的Windows服务都显示在列表框中。接下来,必须获取服务的信息,把它们显示在文本框中。

1. 服务的监视

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

  32-4

 

 

CanPauseAndContinue

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

CanShutdown

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

CanStop

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

DependentServices

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

ServicesDependentOn

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

DisplayName

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

MachineName

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

ServiceName

服务的名称

ServiceType

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

Status

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

在上面的应用程序中,使用DisplayNameServiceNameServiceTypeStatus属性显示服务信息。此外,CanPauseAndContinueCanStop用于启用和禁用PauseContinueStop按钮。

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

方法SetServiceStatus()返回一个字符串,表示服务的类型。根据传送给ServiceType参数的类型返回一个字符串。从ServiceController.ServiceType属性中得到的ServiceType代表一组标记,使用按位OR运算符,可以把这组标记组合在一起。InteractiveProcess位可以与Win32OwnProcessWin32ShareProcess一起设置。首先,在检查其他的值之前,一定要先检查InteractiveProcess位以前是否设置过。使用该服务,返回的字符串是“Win 32 Service Process”或“Win 32 Shared Process”。

  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();

  }

由于控制服务要花费一定的时间,因此,光标在第一个语句中切换为等待光标。然后,根据被按的按钮调用ServiceController方法。使用WaitForStatus()方法,等待服务把状态改为被请求的值,但是,我们最多等待10秒。在10秒之后,就会刷新列表框中的信息,其目的是当用户选择与以前相同的服务时,服务的新状态能够显示出来。

最后运行的应用程序结果如图32-19所示。

  32-19

posted on 2008-07-16 10:53  迷你软件  阅读(825)  评论(0编辑  收藏  举报

本网站绝大部分资源来源于Internet,本站所有作品版权归原创作者所有!!如有以下内容:章节错误、非法内容、作者署名出错、版权疑问、作品内容有违相关法律等请及时与我联系. 我将在第一时间做出响应!本站所有文章观点不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。