NSIS 检查 Windows 服务的状态

发布于 2024-11-05 10:24:47 字数 204 浏览 3 评论 0原文

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

我发现了一个脚本

sc QUERY ServiceNameHere | FIND "RUNNING"

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

请帮忙。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江城子 2024-11-12 10:24:47

如果您可以使用插件:

使用简单服务插件,您可以执行此操作:

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

如果您无法使用插件:

请注意,我在 FIND 中添加了 /C。 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

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
偏闹i 2024-11-12 10:24:47

有几个处理 NT 服务的 NSIS 插件和辅助函数:NSIS 服务库NSIS 简单服务插件NsSCM。 Wiki 概述了所有选项

使用 sc.exe 是有问题的,因为输出可能是本地化的,net.exe 可能更好(并且它也在

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

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}
锦爱 2024-11-12 10:24:47

我使用其 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文