NSIS检查Windows服务的状态

时间:2011-05-06 09:50:56

标签: service nsis

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

我找到了一个脚本

sc QUERY ServiceNameHere | FIND "RUNNING"

但是我找不到如何在NSIS脚本中检查返回结果。

请帮忙。

3 个答案:

答案 0 :(得分:6)

如果您可以使用插件:

使用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. STOPPED
  2. START_PENDING
  3. STOP_PENDING
  4. RUNNING
  5. CONTINUE_PENDING
  6. PAUSE_PENDING
  7. PAUSED
  8. 如果您不能使用插件:

    请注意,我将/ 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
    

答案 1 :(得分:3)

有几个处理NT服务的NSIS插件和辅助函数: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}

答案 2 :(得分:0)

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

因此基于Kyle的解决方案我使用:

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