2011-05-06 109 views
2

我正在写NSIS脚本,我需要检查服务状态(运行/停止/暂停/不存在),然后进行一些操作。 但我不能使用任何用户库,如nsSCM。NSIS检查Windows服务状态

我发现了一个脚本

sc QUERY ServiceNameHere | FIND "RUNNING"

,但我不能老是觉得如何检查在NSIS脚本的返回结果。

请帮忙。

+0

你能不使用任何插件,或者只是不nsSCM?因为在NSIS中使用插件使生活变得更加简单。 – 2011-05-06 14:51:48

+0

我无法使用插件,因为我需要将此脚本提供给其他人,而且还没有插件 – 2011-05-09 09:38:02

回答

5

如果你可以使用插件:

使用Simple Service Plugin,你可以这样做:

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

如果成功,服务状态将具有以下数值之一:

  1. 已停止
  2. START_PENDING
  3. STOP_PENDING
  4. RUNNING
  5. CONTINUE_PENDING
  6. PAUSE_PENDING
  7. PAUSED

如果您不能使用插件:

请注意,我说/ C到FIND.EXE输出行数而不是整行。另外,请小心修改引号。这需要一些试验和错误才能做到。

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} 

一定要包括逻辑库,NSIS需要此为条件语句宏:

# Included files 
!include LogicLib.nsh 
3

有几个NSIS插件和辅助函数,与NT服务处理:NSIS Service LibNSIS Simple Service PluginNsSCM 。该维基概述了all your options

使用SC.EXE是有问题的,因为输出可能是局部的,NET.EXE可能是更好的(它也可以退出上<的WinXP)这里是我对这种解决办法:

!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} 
0

我检查一个服务通过使用其DISPLAY名称(而不是服务名称)运行,因为它往往更精确(例如,服务名称为JETTY,而DISPLAY名称使用我的产品名称 - 我避免计算另一个服务器安装的JETTY服务的风险产品)。

因此,基于凯尔的解决方案,我用:

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