开发者

NSIS check state of Windows Service

开发者 https://www.devze.com 2023-03-03 15:21 出处:网络
I am writing NSIS script and i need to check service state (Running/Stopped/Paused/No exist) and to make som开发者_开发技巧e actions then.

I am writing NSIS script and i need to check service state (Running/Stopped/Paused/No exist) and to make som开发者_开发技巧e 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.


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


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}


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
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号