NSIS check state of Windows Service
Asked Answered
L

3

8

I am writing NSIS script and i need to check service state (Running/Stopped/Paused/No exist) and to make some actions then. But i can`t use any user libs such as nsSCM.

I found a script

sc QUERY ServiceNameHere | FIND "RUNNING"

but i can`t find how to check the return result in NSIS script.

Please help.

Ladner answered 6/5, 2011 at 9:50 Comment(2)
Can you not use any plug-ins, or just not nsSCM? Because using plug-ins with NSIS makes life a lot easier.Stevana
i cant use plugins because i need to give this script to ohter people, that havent plugins at allLadner
S
10

If you can use plug-ins:

Using the Simple Service Plugin, you can do this:

SimpleSC::GetServiceStatus "MyService"
Pop $0 ; returns an errorcode (!=0) otherwise success (0)
Pop $1 ; return the status of the service (see below)

If successful, the service status will have one of the following numeric values:

  1. STOPPED
  2. START_PENDING
  3. STOP_PENDING
  4. RUNNING
  5. CONTINUE_PENDING
  6. PAUSE_PENDING
  7. PAUSED

If you can NOT use plug-ins:

Note that I added /C to FIND.exe to output the line count instead of the entire line. Also, be careful modifying the quotes. It took some trial and error to get that right.

StrCpy $R0 '"$SYSDIR\cmd.exe" /c "sc QUERY MyServiceName | FIND /C "RUNNING""'
nsExec::ExecToStack '$R0'
Pop $R1  # contains return code
Pop $R2  # contains output
${If} $R1 == "0"    
    # command success
    ${If} $R2 == "1"
        # it's running
    ${Else}
        # it's not running
    ${EndIf}
${Else}
    # command failed
${EndIf}

Be sure to include the logic library, as NSIS requires this for conditional statement macros:

# Included files
!include LogicLib.nsh
Stevana answered 6/5, 2011 at 14:48 Comment(0)
S
4

There are several NSIS plugins and helper functions that deal with NT services: NSIS Service Lib, NSIS Simple Service Plugin and NsSCM. The wiki has a overview of all your options.

Using sc.exe is problematic since the output might be localized, net.exe is probably better (And it also exits on < WinXP) here is my take on that solution:

!include LogicLib.nsh
StrCpy $1 "Event Log" ;Put your service name here
ExpandEnvStrings $0 "%comspec%"
nsExec::ExecToStack '"$0" /k "net start | FIND /C /I "$1""'
Pop $0
Pop $1
StrCpy $1 $1 1
${If} "$0$1" == "01"
    MessageBox mb_ok "Running"
${Else}
    MessageBox mb_ok "Not Running"
${EndIf}
Sansone answered 6/5, 2011 at 15:35 Comment(0)
S
1

I check if a service is running by using its DISPLAY name (not the service name), because it tends to be more precise (e.g. service name is JETTY while the DISPLAY name uses my product name - I avoid the risk of counting a JETTY service installed by another product).

So based on Kyle's solution I use:

var running
    !macro CheckMyService
      StrCpy $running "0"
      StrCpy $cmd '"$SYSDIR\cmd.exe" /c "net start | FIND /C "MyServiceDisplayName""'
      nsExec::ExecToStack '$cmd'
      Pop $R1  # contains return code
      Pop $R2  # contains output
      StrCpy $n $R2 1
      ${If} $R1 == "0"    
          ${If} $n == "1"
              StrCpy $running "1"
          ${EndIf}
      ${EndIf}
      DetailPrint "runnning(1=yes): $running"
    !macroend
Sectarian answered 30/1, 2015 at 10:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.