使用更新的图像显示服务状态

时间:2018-12-11 07:28:28

标签: nsis

在安装程序结束时,我们要启动上一步中安装的几个服务并显示其状态。 Kinda就像一堆交通灯,如果相应的服务正在运行,它会从红色变为绿色。

在服务启动时甚至可以显示其实际状态吗? 这应该在一个可以自我更新的屏幕上。

1 个答案:

答案 0 :(得分:1)

在我想像的一页上,最多只能有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 control来显示服务状态。