Solved

Windows service status on desktop

Posted on 2016-10-25
4
55 Views
Last Modified: 2016-11-20
I am looking for a little utility that can run and display the status of a Windows service on the desktop in the form of red light (stopped), green light (running). It would also be nice to be able to click the status to change the service status. I am sure there is a utility already available but I cannot seem to find one.
0
Comment
Question by:murryc
  • 2
4 Comments
 
LVL 13

Assisted Solution

by:Mark Galvin
Mark Galvin earned 50 total points (awarded by participants)
ID: 41860029
Hi you could try something like ManageEngine. Not sure about the facility to have a traffic light system with it.
0
 
LVL 13

Assisted Solution

by:frankhelk
frankhelk earned 50 total points (awarded by participants)
ID: 41860260
Here's some low-cost, abroad idea ... I'd do it with the sysinternals tool BGinfo (see at http://sysinternals.com which is now mapped to Microsoft, wher the tools are residing now). BGInfo is freeware, the remainder of my solution is Windows on-board stuff.

  • Open BGInfo and create a custom field with a name of your choice.
  • Use WMI query as source for that field
  • Insert the field into the background image with some text as shown.
  • Position as desired.
  • Save definition, i.e. as C:\bginfo\service.bgi
  • Create a planned task with appropriate schedule that calls "(path)\BGinfo.exe C:\bginfo\service.bgi /TIMER:0 /accepteula

Screenshot snippets:
Step1.pngStep2.pngStep2.1.pngStep3.pngStep4.png
Have fun ...

P.S.:
That solution would not allow to change the service status, it only provides some simple way to display it. An elegant side effect is that the info is embedded into the desktop without standing in the way of regular windows ...

For start and stop there's a simple way: Create some desktop links with the commands
NET START theService
NET STOP theService

Open in new window


The service name could be found in the registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services ... the keys underneath it are the names to be used in the NET  commands. Another way would be the command line tool WMIC:
wmic service get name, tagid

Open in new window


That would list the long name and the name to be used in the NET START and NET STOP commands.

By the way,
wmic service where name="theService" get started

Open in new window

would return the run status (TRUE, FALSE or sth. like "no instances found") of the service (could be used in combination with FIND for simple batches).
0
 
LVL 83

Accepted Solution

by:
oBdA earned 400 total points (awarded by participants)
ID: 41866013
For the fun of it, a Powershell solution.
Save this as Watch-Service.ps1 or Whatever.ps1, and put the .ico files from the attached archive into the script's folder (remove the .img extensions after unzipping - for whatever reason, .ico is not in the list allowed by EE).
Feel free to replace the icons with artwork of your own.
<#
.SYNOPSIS
Monitors one or more local services.
.DESCRIPTION
The script Watch-Service.ps1 monitors if one or more local services are running.
The results will be displayed in form of a Notify icon in the system tray.
The monitored services can be stopped or started using the icon's context menu.
The System tray icon will be 
  - green if all monitored services are running,
  - yellow if at least one service is neither "Running" nor "Stopped",
  - red if at least one service is "Stopped".
In the context menu, each service will have its own menu, and will display its own icon in the appropriate color.
.PARAMETER Name
The name(s) of the services to monitor. Use the service's short name, not the display name.
.PARAMETER Interval
The time in seconds between service state updates.
.PARAMETER ShowConsole
Keeps the Powershell console open after displaying the icon; by default, the console will be hidden.
The console can still be hidden and displayed later using the context menu.
.INPUTS
.OUTPUTS
This script creates no output.
.EXAMPLE
.\Watch-Service.ps1 -Name Spooler, Browser -Interval 10
#>
[CmdletBinding()]
Param(
	[Parameter(Mandatory=$True, HelpMessage='The short name for the service(s) to monitor.')][ValidateNotNullOrEmpty()]
	[String[]]$Name,
	[UInt32]$Interval = 60,	## Seconds
	[switch]$ShowConsole
)
#Requires -Version 3.0
 
Function Invoke-FormMain {
[CmdletBinding()]
Param(
	[array]$Service
)
	Function Update-ContextMenu {
		$NotifyColor = 'Green'
		ForEach ($Svc In $Service) {
			$Svc.Refresh()
			Switch ($Svc.Status.ToString()) {
				'Running' {
					$ServiceColor = 'Green'
				}
				'Stopped' {
					$ServiceColor = 'Red'
					$NotifyColor = 'Red'
				}
				Default {
					$ServiceColor = 'Yellow'
					If ($NotifyColor -ne 'Red') {$NotifyColor = 'Yellow'}
				}
			}
			If ($Svc.__MenuStatus.Text -ne $Svc.Status.ToString()) {
				Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] Service '$($Svc.Name)' changed status to '$($Svc.Status.ToString())'." -ForegroundColor Yellow
				$Svc.__MenuFolder.Image = $Icon[$ServiceColor]
				$Svc.__MenuStatus.Text = $Svc.Status.ToString()
			}
		}
		If ($NotifyIcon.Tag -ne $NotifyColor) {
			$NotifyIcon.Tag = $NotifyColor
			$NotifyIcon.Icon = $Icon[$NotifyColor]
		}
	}
	
	$FormMain = New-Object -TypeName 'System.Windows.Forms.Form'
	$FormMain.WindowState = 'Minimized'
	$FormMain.ShowInTaskbar = $False
	
	$Icon = @{}
	'Gray', 'Green', 'Red', 'Yellow' | ForEach-Object {$Icon[$_] = New-Object -TypeName 'System.Drawing.Icon' -ArgumentList "$($ScriptItem.DirectoryName)\cog_$($_).ico"}
	
	$NotifyIcon = New-Object -TypeName 'System.Windows.Forms.NotifyIcon'
	$NotifyIcon.Icon = $Icon['Gray']
	$NotifyIcon.Tag = 'Gray'
	$NotifyIcon.ContextMenuStrip = New-Object -TypeName 'System.Windows.Forms.ContextMenuStrip'
	$NotifyIcon.Visible = $True
	
	ForEach ($Svc In $Service) {
		Add-Member -InputObject $Svc -MemberType NoteProperty -Name '__MenuFolder' -Value (New-Object -TypeName System.Windows.Forms.ToolStripMenuItem -ArgumentList $Svc.Name)
		Add-Member -InputObject $Svc -MemberType NoteProperty -Name '__MenuStatus' -Value (New-Object -TypeName System.Windows.Forms.ToolStripMenuItem -ArgumentList '...')
		$Svc.__MenuStatus.Enabled = $False
		[void]$Svc.__MenuFolder.DropDownItems.Add($Svc.__MenuStatus)
		Add-Member -InputObject $Svc -MemberType NoteProperty -Name '__MenuSep' -Value (New-Object -TypeName System.Windows.Forms.ToolStripSeparator)
		[void]$Svc.__MenuFolder.DropDownItems.Add($Svc.__MenuSep)
		Add-Member -InputObject $Svc -MemberType NoteProperty -Name '__MenuStart' -Value (New-Object -TypeName System.Windows.Forms.ToolStripMenuItem -ArgumentList 'Start')
		$Svc.__MenuStart.Name = $Svc.Name
		$Svc.__MenuStart.add_Click({
			Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] Sending Start signal to service '$($args[0].Name)'." -ForegroundColor White
			Start-Service -Name $args[0].Name
		})
		[void]$Svc.__MenuFolder.DropDownItems.Add($Svc.__MenuStart)
		Add-Member -InputObject $Svc -MemberType NoteProperty -Name '__MenuStop' -Value (New-Object -TypeName System.Windows.Forms.ToolStripMenuItem -ArgumentList 'Stop')
		$Svc.__MenuStop.Name = $Svc.Name
		$Svc.__MenuStop.add_Click({
			Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] Sending Stop signal to service '$($args[0].Name)'." -ForegroundColor White
			Stop-Service -Name $args[0].Name -Force
		})
		[void]$Svc.__MenuFolder.DropDownItems.Add($Svc.__MenuStop)
		
		[void]$NotifyIcon.ContextMenuStrip.Items.Add($Svc.__MenuFolder)
	}
	
	$MenuItem = [ordered]@{}
	$MenuItem['Separator_Services'] = New-Object -TypeName System.Windows.Forms.ToolStripSeparator
	$MenuItem['Refresh'] = New-Object -TypeName System.Windows.Forms.ToolStripMenuItem -ArgumentList 'Refresh'
	$MenuItem['Console'] = New-Object -TypeName System.Windows.Forms.ToolStripMenuItem -ArgumentList $(If ($ShowConsole) {'Hide Console'} Else {'Show Console'})
	$MenuItem['Separator_Exit'] = New-Object -TypeName System.Windows.Forms.ToolStripSeparator
	$MenuItem['Exit'] = New-Object -TypeName System.Windows.Forms.ToolStripMenuItem -ArgumentList 'Exit'
	$MenuItem.Keys | ForEach-Object {[void]$NotifyIcon.ContextMenuStrip.Items.Add($MenuItem[$_])}
	Update-ContextMenu
	
	$MenuItem['Refresh'].add_Click({
		Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] Received manual refresh request." -ForegroundColor White
		Update-ContextMenu
	})
	$MenuItem['Console'].add_Click({
		If ($MenuItem['Console'].Text -eq 'Show Console') {
			[void]$User32Dll::ShowWindowAsync($MainWindowHandle, 1)
			$MenuItem['Console'].Text = 'Hide Console'
		} Else {
			[void]$User32Dll::ShowWindowAsync($MainWindowHandle, 0)
			$MenuItem['Console'].Text = 'Show Console'
		}
	})
	$MenuItem['Exit'].add_Click({
		$FormMain.Close()
	})
	
	$Timer = New-Object System.Windows.Forms.Timer
	$Timer.Interval =  $Script:Interval * 1000  # ms
	$Timer.add_Tick({Update-ContextMenu})

	$MainWindowHandle = (Get-Process -PID $PID).MainWindowHandle
	If (-not $ShowConsole) {
		[void]$User32Dll::ShowWindowAsync($MainWindowHandle, 0)
	}
	$Timer.Start()
	[void][System.Windows.Forms.Application]::Run($FormMain)
	[void]$User32Dll::ShowWindowAsync($MainWindowHandle, 1)
	$Timer.Stop()
	$NotifyIcon.Visible = $False
}

$ScriptItem = Get-Item -Path $MyInvocation.MyCommand.Path
Add-Type -AssemblyName 'System.Windows.Forms'
$User32Dll = Add-Type -PassThru -Name User32Dll -MemberDefinition @'
	[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
'@
Invoke-FormMain -Service ($Name | % {Get-Service -Name $_ -ErrorAction Stop})

Open in new window

ScreenshotIcons_RemoveExtensionBmpAfterUnzip.zip
0
 
LVL 83

Expert Comment

by:oBdA
ID: 41894648
The script fulfills all of murryc's requirements  - displays one or more service's state as a Tray icon, and allows to change its state from the icon's context menu.
0

Featured Post

Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

Join & Write a Comment

Recently, an awarded photographer, Selina De Maeyer (http://www.selinademaeyer.com/), completed a photo shoot of a beautiful event (http://www.sintjacobantwerpen.be/verslag-en-fotoreportage-van-de-sacramentsprocessie-door-antwerpen#thumbnails) in An…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This tutorial will walk an individual through the steps necessary to configure their installation of BackupExec 2012 to use network shared disk space. Verify that the path to the shared storage is valid and that data can be written to that location:…
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles to another domain controller. Log onto the new domain controller with a user account t…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now