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

Nsis 使用更新的图像显示服务状态,nsis,Nsis,在安装程序的末尾,我们希望启动前一步中安装的几个服务,并显示它们的状态。 有点像一堆交通灯,如果相应的服务正在运行,它们会从红色变为绿色 这甚至可以显示服务启动时的实际状态吗? 这应该在一个屏幕上进行自我更新。16服务几乎是一个页面可以容纳的极限,我想,但在本例中,我只使用了两个: !include LogicLib.nsh !include Win\COM.nsh !define /IfNDef VT_BOOL 11 !define /IfNDef CLSID_Shell {13709620-

在安装程序的末尾,我们希望启动前一步中安装的几个服务,并显示它们的状态。 有点像一堆交通灯,如果相应的服务正在运行,它们会从红色变为绿色

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

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
!包括LogicLib.nsh
!包括Win\COM.nsh
!定义/IfNDef VT\u BOOL 11
!定义/IfNDef CLSID_外壳{13709620-C279-11CE-A49E-444553540000}
!ifndef IID_ISHELLDISPATCH 2
!定义IID_IShellDispatch2{A4C6892C-3BA9-11d2-9DEA-00C04FB16162}
${NSISCOMIFACEDECL}IShellDispatch2 IServiceRunning 36(w,p)i
!恩迪夫
功能是服务性的;这应该适用于Win2000+,对于任何旧版本,都必须直接调用EnumServicesStatus
Exch$1
推送$0
!insertmacro ComHlpr_CreateInProcInstance${CLSID_Shell}${IID_IShellDispatch2}r0“”
${If}$0 P 0
推1美元
${IShellDispatch2::IsServiceRunning}$0'(s,@r1)'
${IUnknown::Release}$0“”
系统::调用“*$1(&i2.r0,&i6,&i2.r1)”$如果服务正在运行,则1将为0
${IfThen}$0${VT_BOOL}${{124;}StrCpy$10${};如果我们失败了,那就不算什么了
${Else}
StrCpy$10
${EndIf}
流行音乐$0
Exch$1
功能端
!包括nsDialogs.nsh
!包括WinMessages.nsh
页面文件
页面自定义mySvcPage
部分
; 在此处安装并启动服务
分段结束
!宏更新服务图标控件ico icopath大小
系统::调用'USER32::LoadImage(p0,ts,i${IMAGE\u ICON},i${size},i${size},i${LR\u LOADFROMFILE})p.s'${icopath}
Pop${ico}
推送${ico}
SendMessage${control}${STM_SETIMAGE}${IMAGE_ICON}${ico}${ico}
${NSD_FreeIcon}${ico};释放旧图标
Pop${ico}
!宏端
Var svc1
Var svc1ico
Var svc2
Var svc2ico
Var计数
函数mySvcPage
nsDialogs::创建1018
流行音乐$0
文件“/oname=$PluginsDir\SvcW.ico”“${NSISDIR}\Contrib\Graphics\Icons\llama grey.ico”
文件“/oname=$PluginsDir\SvcR.ico”“${NSISDIR}\Contrib\Graphics\Icons\llama blue.ico”
!宏更新ServiceIConFromServiceState svcname控件ico大小
推送“${svcname}”
呼叫IServiceRunning
流行音乐$0
${If}$0
StrCpy$0“$PluginsDir\SvcR.ico”
输入$count$count+1
${Else}
StrCpy$0“$PluginsDir\SvcW.ico”
${EndIf}
!insertmacro UpdateServiceIcon${control}${ico}$0${size}
!宏端
${NSD_CreateIcon}10u 10u 15u 15u“
Pop$svc1
${NSD_CreateLabel}25u 10u 40u 10u“W32时间”
流行音乐$0
${NSD_CreateIcon}10u 25u 15u 15u“
Pop$svc2
${NSD_CreateLabel}25u 25u 40u 10u“主题”
流行音乐$0
${NSD_CreateTimer}更新服务状态1000
调用UpdateServicesStatus
nsDialogs::Show
${NSD\u KillTimer}更新服务状态
${NSD_FreeIcon}$svc1ico
${NSD_FreeIcon}$svc2ico
功能端
函数UpdateServicesStatus
StrCpy$count 0
!insertmacro UpdateServiceIconFromServiceState“W32Time”$svc1$svc1ico 16
!insertmacro UpdateServiceIconFromServiceState“主题”$svc2$svc2ico 16
GetDlgItem$0$hwndparent 1;下一步/关闭按钮
${If}$count>=2
启用窗口$0 1
${Else}
启用窗口$0
${EndIf}
功能端

如果在编译时不知道服务的数量,或者如果一个页面上容纳的服务太多,则必须使用a来显示服务状态。

此屏幕是否应阻止单击“下一步”,直到所有服务启动?有多少服务?3.5? >10?阻止“下一步”可能是一种选择,但不是必须的。大约有16项服务。