NSSM
We can consider windows applications to exist in two camps, normal processes that own their own lifetime, and processes that implement what Service Control Manager (SCM) expects. Services exist for the sole purpose of running independently of a user, you know the typical ârun forever in the background, start at boot, no user logged in, and be managed centrallyâ.
NSSM (âNon-Sucking Service Managerâ) is basically a tiny wrapper that lets you run any normal Windows program (an .exe, a batch file, PowerShell, etc.) as a proper Windows Service. NSSM sits in the middle: Windows thinks itâs starting a service (NSSM), and NSSM starts your real app, watches it, and can restart it or shut it down cleanly depending on how you configure it.
It is worth noting that NSSM cannot wrap a service, it can only wrap normal processes.
When a service is âan NSSM serviceâ, the important idea is: the serviceâs ImagePath (the thing Windows starts) points to nssm.exe, not your application. Your applicationâs path is stored separately in the registry under the service key (commonly ...\Services\<ServiceName>\Parameters\Application) along with things like AppDirectory and AppParameters. So Services.msc might show âPath to executable = nssm.exeâ even though the real app is elsewhere; thatâs normal for NSSM-managed services.
When a service is âa normal direct serviceâ (not NSSM), the serviceâs ImagePath points straight to your executable (or to some other service host), so Services.msc shows your exe path. In that case there is no NSSM âParameters\Applicationâ concept unless something else created those keys. Thatâs why your Routing 1 and Routing 02 look different: Routing 1 is direct, Routing 02 is wrapped.
Operationally, NSSM needs just three bits of information to start your app: Application (what to run), AppDirectory (working directory), and optionally AppParameters (arguments). If Application is only a bare filename like AccessPay.UPP.SubmissionService.exe, then NSSM relies on AppDirectory being correct and the exe actually being present in that directory at runtime. If either is wrong, NSSM will fail to start and youâll get errors that look like âcannot find the path specifiedâ or generic start failures.
The difference between âinstallâ and âsetâ is the thing that keeps biting people. nssm install <service> <app> creates the service entry (it writes ImagePath to nssm.exe, creates the registry structure, and sets Application to whatever you passed). nssm set <service> <key> <value> just edits NSSMâs stored config for that service. If the service wasnât created with NSSM in the first place (ImagePath points to your exe), then doing nssm set doesnât magically convert it into an NSSM service; it just writes values, but Windows still starts whatever ImagePath says. Thatâs why you can end up with a âmixed fleetâ: one service direct, another NSSM.
Here are the core commands youâll see 95% of the time, with a mental model for each.
# Create an NSSM service (Windows will start nssm.exe)
nssm install "MyService" "C:\Path\To\MyApp.exe"
# Tell NSSM what working directory to use
nssm set "MyService" AppDirectory "C:\Path\To"
# Optional args
nssm set "MyService" AppParameters "--env envName --foo bar"
# Run-as account (username + password)
nssm set "MyService" ObjectName "DOMAIN\User" "SuperSecretPassword"
# Start/stop via Windows
Start-Service "MyService"
Stop-Service "MyService"
There are a few registry locations that matter when youâre debugging, and your screenshots already showed them. HKLM:\SYSTEM\CurrentControlSet\Services\<ServiceName>\ImagePath tells you what Windows will start. If thatâs ...\nssm.exe, itâs NSSM-wrapped. If itâs your app exe, itâs direct. For NSSM-wrapped services, the âreal configâ lives under HKLM:\SYSTEM\CurrentControlSet\Services\<ServiceName>\Parameters\ and you care about Application, AppDirectory, and AppParameters.
$svc = "My.Service.Name"
# What Windows starts
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\$svc" | Select-Object ImagePath, ObjectName
# What NSSM starts (only meaningful if ImagePath is nssm.exe)
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\$svc\Parameters" |
Select-Object Application, AppDirectory, AppParameters