16 сервисов - это почти предел, который вы можете разместить на одной странице, я думаю, но в этом примере я использую только две:
!include LogicLib.nsh
!include Win\COM.nsh
!define /IfNDef VT_BOOL 11
!define /IfNDef CLSID_Shell {13709620-C279-11CE-A49E-444553540000}
!ifndef IID_IShellDispatch2
!define IID_IShellDispatch2 {A4C6892C-3BA9-11d2-9DEA-00C04FB16162}
${NSISCOMIFACEDECL} IShellDispatch2 IsServiceRunning 36 (w,p)i
!endif
Function IsServiceRunning ; This should work on Win2000+, for anything older you must call EnumServicesStatus directly
Exch $1
Push $0
!insertmacro ComHlpr_CreateInProcInstance ${CLSID_Shell} ${IID_IShellDispatch2} r0 ""
${If} $0 P<> 0
Push $1
${IShellDispatch2::IsServiceRunning} $0 '(s,@r1)'
${IUnknown::Release} $0 ""
System::Call '*$1(&i2.r0,&i6,&i2.r1)' ; $1 will be <> 0 if the service is running
${IfThen} $0 <> ${VT_BOOL} ${|} StrCpy $1 0 ${|} ; Not a VT_BOOL, assume we failed
${Else}
StrCpy $1 0
${EndIf}
Pop $0
Exch $1
FunctionEnd
!include nsDialogs.nsh
!include WinMessages.nsh
Page InstFiles
Page Custom mySvcPage
Section
; Install and start services here
SectionEnd
!macro UpdateServiceIcon control ico icopath size
System::Call 'USER32::LoadImage(p0, ts, i ${IMAGE_ICON}, i${size}, i${size}, i${LR_LOADFROMFILE})p.s' "${icopath}"
Pop ${ico}
Push ${ico}
SendMessage ${control} ${STM_SETIMAGE} ${IMAGE_ICON} ${ico} ${ico}
${NSD_FreeIcon} ${ico} ; Free the old icon
Pop ${ico}
!macroend
Var svc1
Var svc1ico
Var svc2
Var svc2ico
Var count
Function mySvcPage
nsDialogs::Create 1018
Pop $0
File "/oname=$PluginsDir\SvcW.ico" "${NSISDIR}\Contrib\Graphics\Icons\llama-grey.ico"
File "/oname=$PluginsDir\SvcR.ico" "${NSISDIR}\Contrib\Graphics\Icons\llama-blue.ico"
!macro UpdateServiceIconFromServiceState svcname control ico size
Push "${svcname}"
Call IsServiceRunning
Pop $0
${If} $0 <> 0
StrCpy $0 "$PluginsDir\SvcR.ico"
IntOp $count $count + 1
${Else}
StrCpy $0 "$PluginsDir\SvcW.ico"
${EndIf}
!insertmacro UpdateServiceIcon ${control} ${ico} $0 ${size}
!macroend
${NSD_CreateIcon} 10u 10u 15u 15u ""
Pop $svc1
${NSD_CreateLabel} 25u 10u 40u 10u "W32Time"
Pop $0
${NSD_CreateIcon} 10u 25u 15u 15u ""
Pop $svc2
${NSD_CreateLabel} 25u 25u 40u 10u "Themes"
Pop $0
${NSD_CreateTimer} UpdateServicesStatus 1000
Call UpdateServicesStatus
nsDialogs::Show
${NSD_KillTimer} UpdateServicesStatus
${NSD_FreeIcon} $svc1ico
${NSD_FreeIcon} $svc2ico
FunctionEnd
Function UpdateServicesStatus
StrCpy $count 0
!insertmacro UpdateServiceIconFromServiceState "W32Time" $svc1 $svc1ico 16
!insertmacro UpdateServiceIconFromServiceState "Themes" $svc2 $svc2ico 16
GetDlgItem $0 $hwndparent 1 ; Next/Close button
${If} $count >= 2
EnableWindow $0 1
${Else}
EnableWindow $0 0
${EndIf}
FunctionEnd
Если количество сервисов неизвестно во время компиляцииили если их слишком много, чтобы поместиться на странице, то вместо этого вы должны использовать элемент управления ListView для отображения статуса службы.