NSIS проверяет состояние службы Windows

#service #nsis

#Обслуживание #nsis

Вопрос:

Я пишу скрипт NSIS, и мне нужно проверить состояние службы (запущено / остановлено / приостановлено / Не существует) и затем выполнить некоторые действия. Но я не могу использовать какие-либо пользовательские библиотеки, такие как nsSCM.

Я нашел скрипт

sc QUERY ServiceNameHere | FIND "RUNNING"

но я не могу найти, как проверить возвращаемый результат в скрипте NSIS.

Пожалуйста, помогите.

Комментарии:

1. Можете ли вы не использовать какие-либо плагины или просто не nsSCM? Потому что использование подключаемых модулей с NSIS значительно упрощает жизнь.

2. я вообще не могу t use plugins because i need to give this script to ohter people, that haven подключать плагины

Ответ №1:

Если вы можете использовать подключаемые модули:

Используя простой служебный плагин, вы можете сделать это:

 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. Выполняется
  5. CONTINUE_PENDING
  6. ПРИОСТАНОВКА выполнения
  7. ПРИОСТАНОВЛЕНО

Если вы не можете использовать подключаемые модули:

Обратите внимание, что я добавил / C в FIND.exe для вывода количества строк вместо всей строки. Кроме того, будьте осторожны, изменяя кавычки. Потребовалось несколько проб и ошибок, чтобы все исправить.

 StrCpy $R0 '"$SYSDIRcmd.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
  

Ответ №2:

Существует несколько плагинов и вспомогательных функций NSIS, которые имеют дело со службами NT: NSIS Service Lib, NSIS Simple Service Plugin и NsSCM. В wiki есть обзор всех ваших опций.

Используя 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}
  

Ответ №3:

Я проверяю, запущена ли служба, используя ее отображаемое имя (не название службы), потому что оно имеет тенденцию быть более точным (например, имя службы — JETTY, в то время как отображаемое имя использует название моего продукта — я избегаю риска подсчета службы JETTY, установленной другим продуктом).

Итак, основываясь на решении Кайла, я использую:

 var running
    !macro CheckMyService
      StrCpy $running "0"
      StrCpy $cmd '"$SYSDIRcmd.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