Author Posts

December 8, 2017 at 9:10 pm

I am trying to create a service with PowerShell scripting using NSSM – the Non-Sucking Service Manager I have the startup part working great. Now I am trying to right click on the Service choose stop and gracefully shutdown. NSSM says it sends WM_CLOSE and then WM_QUIT messages how do I read these in PowerShell?
After I start everything up my code enters a do { start-sleep -s 5 loop forever} while (1 -eq 1 ) so I can just read the message inside the loop shutdown everything and then exit the PowerShell script.

December 9, 2017 at 9:41 pm

I've never made any attempt to use NSSM, since you can create services with Visual Studio easily, including using the free Visual Studio Community version. One you get into underlying interface stuff, you have to resort to dev-like efforts. PoSH does a huge number of things, but it does not do everything for you. Many times, you are going to have to dig and write the needed items for your use case yourself.

Shouldn't the NSSM interface provide this access methods to you, since it is the one doing this?

The WM_CLOSE, WM_QUIT methods are part of a Windows Class,

... generally accessed doing stuff like this:

$src = @'
using System;
using System.Runtime.InteropServices;
public static class Win32 {
public static uint WM_CLOSE = 0x10;

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

Add-Type -TypeDefinition $src
$zero = [IntPtr]::Zero
$p = @(Get-Process Notepad)[0]
[Win32]::SendMessage($p.MainWindowHandle, [Win32]::WM_CLOSE, $zero, $zero) > $null

Of course, as I said, I have never spent anytime messing with NSSM, but if it were me, I'd contact them first and ask how they are doing this and how one can get at the underlying stuff.

December 11, 2017 at 10:20 pm

After looking at it again NSSM has a shutdown tab, I unchecked all the boxes, then in the PowerShell script read the service status through $Service_Status = (get-service $Service_Name).status.tostring().toupper() and look for -ne RUNNING
here is a code snippet.
do {
Start-Sleep -s 5
$Service_Status = (get-service $Service_Name).status.tostring().toupper()
if ($Service_Status -ne 'RUNNING') {
# You want change the write-host to write to an event log or a file because there is no screen output to read.
write-host 'stopping things'
write-host 'stopped things'
exit # leave loop and program
} while (1 -eq 1)

So now if I right click on the service and choose stop it shuts down gracefully 🙂