电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

从Window系统托盘控制Windows服务


发布日期:2019/3/31
 

有许多内建的类可以让我们轻松创建Windows服务程序但如何轻松控制这些服务呢?一般是到管理工具里面进行控制本文将描述如何创建一个运行在系统托盘里的程序来轻松控制一个服务程序至于如何创建服务程序可以参考NET SDK或其它创建服务程序的文章本文的例子利用IIS的WSVC服务来做例子来控制IIS的停止与启动

要开发这样的程序我们先打开Microsoft Visual StudioNET新建一个名为ServiceController的解决方案然后新建名为WinForm的Visual Basic类型的Windows应用程序然后把自动创建的Formvb删除掉因为我们创建的应用程序没有用户界面我们在Sub Main运行程序

先添加引用-NET-SystemServiceProcessdll新建名为modMain的模块代码如下

Imports System<fp class='fp-ax2rz'></fp>TextImports System<fp class='fp-e4fvj'></fp>DiagnosticsImports System<fp class='fp-e4fvj'></fp>ServiceProcessPublic Module modMain Private WithEvents mobNotifyIcon As NotifyIcon Private WithEvents mobContextMenu As ContextMenu Private WithEvents mobTimer As Timers<fp class='fp-fsvyp'></fp>Timer Private mobServiceController As ServiceControllerEnd Module

上面的代码首先引用了三个名称空间然后分别定义了四个变量mobNotifyIcon将会在系统托盘里显示ContextMenu显示菜单信息mobTimer为定时器原来检查服务的状态以随时变更菜单和图标的状态mobServiceController表示Windows服务应用程序并允许连接到正在运行或者已停止的服务对其进行操作或获取有关它的信息

由于服务程序是没有用户界面的因此我们设置三种图标标识服务的状态这里做了三个简单的图标来标识服务的状态RunningicoPausedicoStoppedico分别如下

下面我们就建立定时器SetUpTimer过程通常IIS停止或启动的间隔为我们就用秒来做定时器的间隔代码如下

Private Sub SetUpTimer()TrymobTimer = New Timers<fp class='fp-e4fvj'></fp>Timer()With mobTimer<fp class='fp-ax2rz'></fp>AutoReset = True<fp class='fp-fsvyp'></fp>Interval = <fp class='fp-r5vde'></fp><fp class='fp-z7ief'></fp><fp class='fp-z7ief'></fp><fp class='fp-d9zwb'></fp><fp class='fp-5qsob'></fp>Start()End WithCatch obEx As ExceptionThrow obExEnd TryEnd Sub

下面创建上下文菜单的过程并为每个菜单项添加事件处理程序

Private Sub CreateMenu()TrymobContextMenu<fp class='fp-ax2rz'></fp>MenuItems<fp class='fp-e4fvj'></fp>Add(New MenuItem(<fp class='fp-rt4bw'></fp>停止<fp class='fp-rt4bw'></fp><fp class='fp-9eeua'></fp>New EventHandler(AddressOf StopService)))mobContextMenu<fp class='fp-5qsob'></fp>MenuItems<fp class='fp-fsvyp'></fp>Add(New MenuItem(<fp class='fp-rt4bw'></fp>暂停<fp class='fp-323hg'></fp><fp class='fp-thke2'></fp>New EventHandler(AddressOf PauseService)))mobContextMenu<fp class='fp-e4fvj'></fp>MenuItems<fp class='fp-5qsob'></fp>Add(New MenuItem(<fp class='fp-exfzh'></fp>继续<fp class='fp-sob6f'></fp><fp class='fp-a2uwg'></fp>New EventHandler(AddressOf ContinueService)))mobContextMenu<fp class='fp-fsvyp'></fp>MenuItems<fp class='fp-ax2rz'></fp>Add(New MenuItem(<fp class='fp-sob6f'></fp>开始<fp class='fp-323hg'></fp><fp class='fp-thke2'></fp>New EventHandler(AddressOf StartService)))mobContextMenu<fp class='fp-ax2rz'></fp>MenuItems<fp class='fp-5qsob'></fp>Add(<fp class='fp-rt4bw'></fp><fp class='fp-naabd'></fp><fp class='fp-sob6f'></fp>)mobContextMenu<fp class='fp-ax2rz'></fp>MenuItems<fp class='fp-fsvyp'></fp>Add(New MenuItem(<fp class='fp-exfzh'></fp>关于<fp class='fp-rt4bw'></fp><fp class='fp-mmu87'></fp>New EventHandler(AddressOf AboutBox)))mobContextMenu<fp class='fp-ax2rz'></fp>MenuItems<fp class='fp-ax2rz'></fp>Add(New MenuItem(<fp class='fp-rt4bw'></fp>退出<fp class='fp-323hg'></fp><fp class='fp-a2uwg'></fp>New EventHandler(AddressOf ExitController)))Catch obEx As ExceptionThrow obExEnd TryEnd Sub

当我们改变了服务的运行状态时我们应当向用户反映这一变化这里用托盘的图标不同来进行标识当服务程序启动时就要先建立服务的状态首先GetServiceStatus过程调用ServiceController的Refresh方法它将会刷新的ServiceController所有属性要准确得到服务程序的状态这一过程是至关重要的下面的Select Case语句根据不同的服务程序的状态建立不同的菜单项和托盘图标

Private Sub GetServiceStatus()Try <fp class='fp-yj1b9'></fp>//读取状态之前先进行刷新 mobServiceController<fp class='fp-ax2rz'></fp>Refresh() <fp class='fp-pty82'></fp>//变更菜单项和图标 Select Case mobServiceController<fp class='fp-5qsob'></fp>Status() Case ServiceProcess<fp class='fp-5qsob'></fp>ServiceControllerStatus<fp class='fp-fsvyp'></fp>Paused mobNotifyIcon<fp class='fp-5qsob'></fp>Icon = New Icon(<fp class='fp-sob6f'></fp>Paused<fp class='fp-5qsob'></fp>ico<fp class='fp-rt4bw'></fp>) mobContextMenu<fp class='fp-ax2rz'></fp>MenuItems(<fp class='fp-clqyu'></fp>)<fp class='fp-e4fvj'></fp>Enabled = False mobContextMenu<fp class='fp-ax2rz'></fp>MenuItems(<fp class='fp-qhfb8'></fp>)<fp class='fp-fsvyp'></fp>Enabled = False mobContextMenu<fp class='fp-ax2rz'></fp>MenuItems(<fp class='fp-zo2mf'></fp>)<fp class='fp-fsvyp'></fp>Enabled = True mobContextMenu<fp class='fp-fsvyp'></fp>MenuItems(<fp class='fp-474rm'></fp>)<fp class='fp-e4fvj'></fp>Enabled = False Case ServiceProcess<fp class='fp-e4fvj'></fp>ServiceControllerStatus<fp class='fp-ax2rz'></fp>Running mobNotifyIcon<fp class='fp-e4fvj'></fp>Icon = New Icon(<fp class='fp-sob6f'></fp>Running<fp class='fp-5qsob'></fp>ico<fp class='fp-exfzh'></fp>) mobContextMenu<fp class='fp-5qsob'></fp>MenuItems(<fp class='fp-z7ief'></fp>)<fp class='fp-ax2rz'></fp>Enabled = True mobContextMenu<fp class='fp-ax2rz'></fp>MenuItems(<fp class='fp-qhfb8'></fp>)<fp class='fp-e4fvj'></fp>Enabled = True mobContextMenu<fp class='fp-fsvyp'></fp>MenuItems(<fp class='fp-9ldqc'></fp>)<fp class='fp-ax2rz'></fp>Enabled = False mobContextMenu<fp class='fp-5qsob'></fp>MenuItems(<fp class='fp-474rm'></fp>)<fp class='fp-fsvyp'></fp>Enabled = False Case ServiceProcess<fp class='fp-e4fvj'></fp>ServiceControllerStatus<fp class='fp-fsvyp'></fp>Stopped mobNotifyIcon<fp class='fp-e4fvj'></fp>Icon = New Icon(<fp class='fp-323hg'></fp>Stopped<fp class='fp-ax2rz'></fp>ico<fp class='fp-exfzh'></fp>) mobContextMenu<fp class='fp-5qsob'></fp>MenuItems(<fp class='fp-z7ief'></fp>)<fp class='fp-fsvyp'></fp>Enabled = False mobContextMenu<fp class='fp-fsvyp'></fp>MenuItems(<fp class='fp-qhfb8'></fp>)<fp class='fp-e4fvj'></fp>Enabled = False mobContextMenu<fp class='fp-ax2rz'></fp>MenuItems(<fp class='fp-u51g8'></fp>)<fp class='fp-ax2rz'></fp>Enabled = False mobContextMenu<fp class='fp-fsvyp'></fp>MenuItems(<fp class='fp-flw1n'></fp>)<fp class='fp-e4fvj'></fp>Enabled = True Case _ ServiceProcess<fp class='fp-fsvyp'></fp>ServiceControllerStatus<fp class='fp-fsvyp'></fp>ContinuePending<fp class='fp-a2uwg'></fp> _ ServiceProcess<fp class='fp-5qsob'></fp>ServiceControllerStatus<fp class='fp-5qsob'></fp>PausePending<fp class='fp-9eeua'></fp> _ ServiceProcess<fp class='fp-5qsob'></fp>ServiceControllerStatus<fp class='fp-e4fvj'></fp>StartPending<fp class='fp-thke2'></fp> _ ServiceProcess<fp class='fp-e4fvj'></fp>ServiceControllerStatus<fp class='fp-fsvyp'></fp>StopPending mobNotifyIcon<fp class='fp-ax2rz'></fp>Icon = New Icon(<fp class='fp-323hg'></fp>Paused<fp class='fp-e4fvj'></fp>ico<fp class='fp-sob6f'></fp>) mobContextMenu<fp class='fp-e4fvj'></fp>MenuItems(<fp class='fp-kax3v'></fp>)<fp class='fp-ax2rz'></fp>Enabled = False mobContextMenu<fp class='fp-e4fvj'></fp>MenuItems(<fp class='fp-blaph'></fp>)<fp class='fp-e4fvj'></fp>Enabled = False mobContextMenu<fp class='fp-fsvyp'></fp>MenuItems(<fp class='fp-zo2mf'></fp>)<fp class='fp-ax2rz'></fp>Enabled = False mobContextMenu<fp class='fp-fsvyp'></fp>MenuItems(<fp class='fp-474rm'></fp>)<fp class='fp-ax2rz'></fp>Enabled = False End Select <fp class='fp-yj1b9'></fp>//检查<fp class='fp-dx7ut'></fp>暂停<fp class='fp-2qegt'></fp>和<fp class='fp-ouq3e'></fp>继续<fp class='fp-jgh4o'></fp>使用可用 If mobServiceController<fp class='fp-5qsob'></fp>CanPauseAndContinue = False Then mobContextMenu<fp class='fp-5qsob'></fp>MenuItems(<fp class='fp-42bl5'></fp>)<fp class='fp-ax2rz'></fp>Enabled = False mobContextMenu<fp class='fp-5qsob'></fp>MenuItems(<fp class='fp-zo2mf'></fp>)<fp class='fp-ax2rz'></fp>Enabled = False End IfCatch obEx As ExceptionThrow obExEnd TryEnd Sub

下面建立菜单项的事件处理程序:

<fp class='fp-k4x6u'></fp>//停止服务的过程Private Sub StopService(ByVal sender As Object<fp class='fp-mmu87'></fp> ByVal e As EventArgs)TryIf mobServiceController<fp class='fp-ax2rz'></fp>Status = ServiceProcess<fp class='fp-5qsob'></fp>ServiceControllerStatus<fp class='fp-fsvyp'></fp>Running ThenIf mobServiceController<fp class='fp-fsvyp'></fp>CanStop = True ThenmobServiceController<fp class='fp-5qsob'></fp>Stop()End IfEnd IfCatch obEx As ExceptionThrow obExEnd TryEnd Sub<fp class='fp-yj1b9'></fp>//暂停服务的过程Private Sub PauseService(ByVal sender As Object<fp class='fp-a2uwg'></fp> ByVal e As EventArgs)TryIf Not mobServiceController<fp class='fp-ax2rz'></fp>Status = ServiceProcess<fp class='fp-ax2rz'></fp>ServiceControllerStatus<fp class='fp-ax2rz'></fp>Paused = True ThenIf mobServiceController<fp class='fp-ax2rz'></fp>CanPauseAndContinue = True ThenmobServiceController<fp class='fp-e4fvj'></fp>Pause()End IfEnd IfCatch obEx As ExceptionThrow obExEnd TryEnd Sub<fp class='fp-pty82'></fp>//继续服务程序的过程Private Sub ContinueService(ByVal sender As Object<fp class='fp-mmu87'></fp> ByVal e As EventArgs)TryIf mobServiceController<fp class='fp-e4fvj'></fp>Status = ServiceProcess<fp class='fp-ax2rz'></fp>ServiceControllerStatus<fp class='fp-ax2rz'></fp>Paused = True ThenIf mobServiceController<fp class='fp-e4fvj'></fp>CanPauseAndContinue = True ThenmobServiceController<fp class='fp-e4fvj'></fp>Continue()End IfEnd IfCatch obEx As ExceptionThrow obExEnd TryEnd Sub<fp class='fp-ks64c'></fp>//开始服务程序的过程Private Sub StartService(ByVal sender As Object<fp class='fp-a2uwg'></fp> ByVal e As EventArgs)TryIf mobServiceController<fp class='fp-fsvyp'></fp>Status = ServiceProcess<fp class='fp-e4fvj'></fp>ServiceControllerStatus<fp class='fp-ax2rz'></fp>Stopped ThenmobServiceController<fp class='fp-fsvyp'></fp>Start()End IfCatch obEx As ExceptionThrow obExEnd TryEnd Sub<fp class='fp-pty82'></fp>//<fp class='fp-07qj4'></fp>关于<fp class='fp-jgh4o'></fp>菜单项的过程Private Sub AboutBox(ByVal sender As Object<fp class='fp-thke2'></fp> ByVal e As EventArgs)TryDim obStringBuilder As New StringBuilder()With obStringBuilder<fp class='fp-5qsob'></fp>Append(<fp class='fp-rt4bw'></fp>Service Controller 使用例子<fp class='fp-sob6f'></fp>)<fp class='fp-ax2rz'></fp>Append(vbCrLf)<fp class='fp-fsvyp'></fp>Append(<fp class='fp-rt4bw'></fp>CLR 版本<fp class='fp-f94z5'></fp><fp class='fp-rt4bw'></fp>)<fp class='fp-fsvyp'></fp>Append(Environment<fp class='fp-ax2rz'></fp>Version<fp class='fp-ax2rz'></fp>ToString)MsgBox(<fp class='fp-ax2rz'></fp>ToString<fp class='fp-9eeua'></fp> MsgBoxStyle<fp class='fp-ax2rz'></fp>Information)End WithobStringBuilder = NothingCatch obEx As ExceptionThrow obExEnd TryEnd Sub<fp class='fp-pty82'></fp>//退出服务程序的过程Private Sub ExitController(ByVal sender As Object<fp class='fp-thke2'></fp> ByVal e As EventArgs)TrymobTimer<fp class='fp-ax2rz'></fp>Stop()mobTimer<fp class='fp-5qsob'></fp>Dispose()mobNotifyIcon<fp class='fp-5qsob'></fp>Visible = FalsemobNotifyIcon<fp class='fp-fsvyp'></fp>Dispose()mobServiceController<fp class='fp-ax2rz'></fp>Dispose()Application<fp class='fp-5qsob'></fp>Exit()Catch obEx As ExceptionThrow obExEnd TryEnd Sub<fp class='fp-yj1b9'></fp>//定时器停止Public Sub mobTimer_Elapsed(ByVal sender As Object<fp class='fp-9eeua'></fp> ByVal e As System<fp class='fp-fsvyp'></fp>Timers<fp class='fp-e4fvj'></fp>ElapsedEventArgs) _Handles mobTimer<fp class='fp-5qsob'></fp>ElapsedTryGetServiceStatus()Catch obEx As ExceptionThrow obExEnd TryEnd Sub<fp class='fp-k4x6u'></fp>//系统托盘图标单击事件Public Sub mobNotifyIcon_Click(ByVal sender As Object<fp class='fp-9eeua'></fp> ByVal e As System<fp class='fp-ax2rz'></fp>EventArgs) _Handles mobNotifyIcon<fp class='fp-5qsob'></fp>ClickSystem<fp class='fp-fsvyp'></fp>Diagnostics<fp class='fp-e4fvj'></fp>Process<fp class='fp-5qsob'></fp>Start(<fp class='fp-rt4bw'></fp>IExplore<fp class='fp-5qsob'></fp>exe<fp class='fp-323hg'></fp><fp class='fp-mmu87'></fp> <fp class='fp-323hg'></fp><fp class='fp-exfzh'></fp>)End Sub

下面就是主程序

Public Sub Main()Try<fp class='fp-yj1b9'></fp>//建立与服务程序的连接mobServiceController = New System<fp class='fp-fsvyp'></fp>ServiceProcess<fp class='fp-e4fvj'></fp>ServiceController(<fp class='fp-rt4bw'></fp>IISAdmin<fp class='fp-exfzh'></fp>)<fp class='fp-k4x6u'></fp>//隐藏图标<fp class='fp-n6918'></fp>知道菜单项和图标准备好以后<fp class='fp-vopex'></fp>mobNotifyIcon = New NotifyIcon()mobNotifyIcon<fp class='fp-fsvyp'></fp>Visible = FalsemobContextMenu = New ContextMenu()CreateMenu()mobNotifyIcon<fp class='fp-5qsob'></fp>ContextMenu = mobContextMenumobNotifyIcon<fp class='fp-5qsob'></fp>Text = <fp class='fp-323hg'></fp>【孟宪会之精彩世界】<fp class='fp-323hg'></fp> + _Microsoft<fp class='fp-fsvyp'></fp>VisualBasic<fp class='fp-ax2rz'></fp>ChrW(<fp class='fp-blaph'></fp><fp class='fp-d9zwb'></fp>) + <fp class='fp-rt4bw'></fp><fp class='fp-rt4bw'></fp>SetUpTimer()mobNotifyIcon<fp class='fp-ax2rz'></fp>Visible = TrueApplication<fp class='fp-fsvyp'></fp>Run()Catch obEx As ExceptionMsgBox(obEx<fp class='fp-5qsob'></fp>Message<fp class='fp-5qsob'></fp>ToString<fp class='fp-thke2'></fp> MsgBoxStyle<fp class='fp-fsvyp'></fp>Critical)EndEnd TryEnd Sub

运行结果如下

上一篇:针对Web设计模式的领悟

下一篇:在Windows应用程序中支持拖拽的TreeView控件