NSIS check state of Windows Service
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:
- STOPPED
- START_PENDING
- STOP_PENDING
- RUNNING
- CONTINUE_PENDING
- PAUSE_PENDING
- 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
精彩评论