#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)
В случае успеха статус службы будет иметь одно из следующих числовых значений:
- ОСТАНОВЛЕНО
- START_PENDING
- STOP_PENDING
- Выполняется
- CONTINUE_PENDING
- ПРИОСТАНОВКА выполнения
- ПРИОСТАНОВЛЕНО
Если вы не можете использовать подключаемые модули:
Обратите внимание, что я добавил / 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