本帖最后由 holley 于 2024-2-8 08:40 编辑
最近写一个小工具,卡在这了
早上又回顾了一下,感觉我脑子一片浆糊的原因,在于自己对于数组、索引与函数调用的关系理解不深,导致越试越迷糊。
函数调用的是标签控件的IDFunc _CheckAndUpdateStatus($nLabelID, $sStatus, $nColor)
GUICtrlSetData($nLabelID, $sStatus)
GUICtrlSetColor($nLabelID, $nColor)
EndFunc ;==>_CheckAndUpdateStatus
现在就是要对应刷新不同分组框内标签控件的ID,而这个ID在未使用分组框之前是通过顺序遍历数组得到的对应关系。
为什么现在分组框添加以后,我也分别做了必选和可选的索引数组,但函数却没有实时获取到标签的刷新了呢?
我到底是需要更新函数或参数还是要重新优化分组框内的数组遍历方式?
目前界面布局基本已经处理好了。
现在遇到的主要问题是:
未做分组框之前,采用遍历数组的方式,$aCheckboxes与$gLabel_Status是可以同步刷新状态的。For $i = 0 To UBound($aSoftwareList) - 1
$aCheckboxes[$i] = GUICtrlCreateCheckbox($aSoftwareList[$i][0], 10, 10 + ($i * 28), 100, 20)
$gLabel_Status[$i] = GUICtrlCreateLabel("检测中...", 138, 13 + ($i * 28), 300, 20)
Next
现在分组框添加后,反复折腾了几次,,索引状态同步不起来,函数刷新的$gLabel_Status不生效了
可直接下载附件,看现成的脚本和ini配置。
脚本如下:Global Const $sProductName = "常用插件安装器"
Global Const $sProductVersion = "xxx"
Global Const $sIniPath = @ScriptDir & "\runtime.ini"
$softwareCount = IniRead($sIniPath, "SoftwareList", "Count", "NotFound")
$MandatoryCount = IniRead($sIniPath, "SoftwareList", "MandatoryCount", "NotFound")
$OptionalCount = IniRead($sIniPath, "SoftwareList", "OptionalCount", "NotFound")
If $softwareCount = "NotFound" Or $softwareCount = 0 Or $MandatoryCount = "NotFound" Or $MandatoryCount = 0 Or $OptionalCount = "NotFound" Or $OptionalCount = 0 Then
MsgBox(0, "Error", "INI配置文件中未找到软件数量,请修改!")
Exit
EndIf
Global $aSoftwareList[$softwareCount][5]
For $i = 1 To $softwareCount
$sSection = "Software" & $i
$softwareName = IniRead($sIniPath, $sSection, "Name", "")
$softwareURL = IniRead($sIniPath, $sSection, "URL", "")
$softwareSaveAs = IniRead($sIniPath, $sSection, "SaveAs", "")
$softwareParameters = IniRead($sIniPath, $sSection, "Parameters", "")
$softwareOption = IniRead($sIniPath, $sSection, "Option", "")
$aSoftwareList[$i - 1][0] = $softwareName
$aSoftwareList[$i - 1][1] = $softwareURL
$aSoftwareList[$i - 1][2] = @TempDir & "" & $softwareSaveAs
$aSoftwareList[$i - 1][3] = $softwareParameters
$aSoftwareList[$i - 1][4] = $softwareOption
Next
Global $aMandatorySoftwareList[$MandatoryCount][5], $MandatoryIndex = 0
Global $aOptionalSoftwareList[$OptionalCount][5], $OptionalIndex = 0
For $i = 0 To $softwareCount - 1
If $aSoftwareList[$i][4] = "0" Or $aSoftwareList[$i][4] = "" Then
For $j = 0 To 4
$aMandatorySoftwareList[$MandatoryIndex][$j] = $aSoftwareList[$i][$j]
Next
$MandatoryIndex += 1
Else
For $j = 0 To 4
$aOptionalSoftwareList[$OptionalIndex][$j] = $aSoftwareList[$i][$j]
Next
$OptionalIndex += 1
EndIf
Next
Global $aSoftwareNames[$softwareCount]
Global $aCheckboxes[$softwareCount]
Global $gLabel_Status[$softwareCount]
; 创建GUI
Local $iGUIWidth = 800
Local $iGroupWidth = ($iGUIWidth / 2) - 30
Local $iGroupStartY = 20
Local $iHeightPerItem = 30
Local $iSpacing = 10
Local $iGroupPadding = 40
Local $iButtonHeight = 35
Local $iButtonWidth = 155
Local $iButtonSpacing = -45
Local $iButtonPadding = 20
Local $iGroupHeightMandatory = $iHeightPerItem * $MandatoryCount + ($MandatoryCount - 1) * $iSpacing + $iGroupPadding
Local $iGroupHeightOptional = $iHeightPerItem * $OptionalCount + ($OptionalCount - 1) * $iSpacing + $iGroupPadding
Local $iGroupStartY_Optional = $iGroupStartY + $iGroupHeightMandatory + $iSpacing
Local $iMaxGroupHeight = ($iGroupHeightMandatory > $iGroupHeightOptional) ? $iGroupHeightMandatory : $iGroupHeightOptional
Local $iGUIHeight = $iGroupStartY + $iGroupHeightMandatory + $iGroupHeightOptional + $iButtonHeight + $iButtonSpacing + $iButtonPadding
$hGUI = GUICreate($sProductName & " - " & $sProductVersion, $iGUIWidth, $iGUIHeight, -1, -1, $WS_SYSMENU)
Local $iCheckboxWidth = $iGroupWidth - 248
Local $iCheckboxHeight = 20
Local $iLabelWidth = $iCheckboxWidth + 60
Local $iLabelHeight = 20
Global $aMandatoryCheckboxes[$MandatoryCount]
Global $gMandatoryLabel_Status[$MandatoryCount]
Global $aOptionalCheckboxes[$OptionalCount]
Global $gOptionalLabel_Status[$OptionalCount]
$gGroup_Mandatory = GUICtrlCreateGroup("必选组件", 20, $iGroupStartY, $iGroupWidth, $iGroupHeightMandatory)
For $i = 0 To $MandatoryCount - 1
Local $iCheckboxTop = $iGroupStartY + 20 + $i * ($iHeightPerItem + $iSpacing)
Local $softwareName = $aMandatorySoftwareList[$i][0]
$aMandatoryCheckboxes[$i] = GUICtrlCreateCheckbox($softwareName, 40, $iCheckboxTop, $iCheckboxWidth, $iCheckboxHeight)
$gMandatoryLabel_Status[$i] = GUICtrlCreateLabel("检测中...", 180, $iCheckboxTop + 3, $iLabelWidth, $iLabelHeight)
Next
GUICtrlCreateGroup("", -99, -99, 1, 1)
$gGroup_Optional = GUICtrlCreateGroup("可选组件", 20 + $iGroupWidth + 20, $iGroupStartY, $iGroupWidth, $iGroupHeightOptional)
For $i = 0 To $OptionalCount - 1
Local $iCheckboxTop = $iGroupStartY + 20 + $i * ($iHeightPerItem + $iSpacing)
Local $softwareName = $aOptionalSoftwareList[$i][0]
$aOptionalCheckboxes[$i] = GUICtrlCreateCheckbox($softwareName, 40 + $iGroupWidth + 20, $iCheckboxTop, $iCheckboxWidth, $iCheckboxHeight)
$gOptionalLabel_Status[$i] = GUICtrlCreateLabel("检测中...", 180 + $iGroupWidth + 20, $iCheckboxTop + 3, $iLabelWidth, $iLabelHeight)
Next
GUICtrlCreateGroup("", -99, -99, 1, 1)
Local $iButtonY = $iGUIHeight - $iButtonHeight * 2 - $iButtonPadding * 2
$gButton_Install = GUICtrlCreateButton("开始安装", ($iGUIWidth / 2) - 180, $iButtonY, $iButtonWidth, $iButtonHeight)
$gButton_Cancel = GUICtrlCreateButton("取消", ($iGUIWidth / 2) + 32, $iButtonY, $iButtonWidth, $iButtonHeight)
Global $gCancelled = False
GUISetState(@SW_SHOW)
Sleep(500)
If _CheckOAPlugin() Then
_CheckAndUpdateStatus($gLabel_Status[3], "新OA插件已安装", 0x008000)
GUICtrlSetState($aCheckboxes[3], $GUI_UNCHECKED)
Else
_CheckAndUpdateStatus($gLabel_Status[3], "新OA插件未安装", 0xFF0000)
GUICtrlSetState($aCheckboxes[3], $GUI_CHECKED)
EndIf
Sleep(500)
_CheckOFD()
Sleep(500)
Global $aPIDs[5] = [0, 0, 0, 0, 0]
; 处理GUI消息
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case $gButton_Install
GUICtrlSetData($gButton_Install, "正在安装请稍候...")
GUICtrlSetState($gButton_Install, $GUI_DISABLE)
For $i = 0 To UBound($aSoftwareList) - 1
If GUICtrlRead($aCheckboxes[$i]) = $GUI_CHECKED Then
_DownloadAndInstall($i)
Sleep(100)
EndIf
Next
Case $gButton_Cancel
For $i = 0 To UBound($aPIDs) - 1
If $aPIDs[$i] <> 0 And ProcessExists($aPIDs[$i]) Then
ProcessClose($aPIDs[$i])
EndIf
Next
Exit
EndSwitch
Sleep(100)
WEnd
GUIDelete()
Exit
Func _DownloadAndInstall($nSoftwareIndex)
Local $sSoftwareName = $aSoftwareList[$nSoftwareIndex][0]
Local $sDownloadURL = $aSoftwareList[$nSoftwareIndex][1]
Local $sSavePath = $aSoftwareList[$nSoftwareIndex][2]
Local $sInstallParams = $aSoftwareList[$nSoftwareIndex][3]
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "下载中,请稍候...", 0x000000)
Local $hDownload = InetGet($sDownloadURL, $sSavePath, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
If @error Then
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "下载失败", 0x000000)
GUICtrlSetData($gButton_Install, "请重试!")
GUICtrlSetState($gButton_Install, $GUI_ENABLE)
Return
EndIf
Do
Sleep(250)
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "下载 " & $aSoftwareList[$i][0] & "... " & Round(InetGetInfo($hDownload, 0) / 1024) & " KB 已下载", 0x000000)
If GUIGetMsg() = $gButton_Cancel Then
$gCancelled = True
InetClose($hDownload)
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "下载已取消", 0xFF0000)
Return
EndIf
Sleep(100)
Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE) Or $gCancelled
If $gCancelled Then Return
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装中,请勿操作键鼠...", 0x0000FF)
Local $sInstallCmd = '"' & $sSavePath & '" ' & $sInstallParams
$aPIDs[$nSoftwareIndex] = Run(@ComSpec & " /c " & $sInstallCmd, "", @SW_HIDE)
If $aPIDs[$nSoftwareIndex] = 0 Then
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装启动失败", 0xFF0000)
Return
EndIf
While ProcessExists($aPIDs[$nSoftwareIndex])
Sleep(100)
If GUIGetMsg() = $gButton_Cancel Then
ProcessClose($aPIDs[$nSoftwareIndex])
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装已取消", 0xFF0000)
Return
EndIf
WEnd
If @error Then
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装失败", 0xFF0000)
Else
_CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装完成", 0x008000)
GUICtrlSetState($aCheckboxes[$nSoftwareIndex], $GUI_UNCHECKED)
If FileExists($sSavePath) Then
FileDelete($sSavePath)
EndIf
EndIf
Local $bAllDone = True
For $i = 0 To UBound($aSoftwareList) - 1
If ProcessExists($aPIDs[$i]) Then
$bAllDone = False
ExitLoop
EndIf
Next
If $bAllDone Then
GUICtrlSetData($gButton_Install, "开始安装")
GUICtrlSetState($gButton_Install, $GUI_ENABLE)
EndIf
EndFunc ;==>_DownloadAndInstall
Func _CheckOAPlugin()
Local $i, $sKey
Local $sRegPath64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Local $sRegPath32 = "HKLM32\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
For $i = 1 To 2
Local $sRegPath = ($i == 1) ? $sRegPath64 : $sRegPath32
Local $j = 1
While 1
$sKey = RegEnumKey($sRegPath, $j)
If @error Then ExitLoop
If $sKey = "{6694F1FD-528D-49C5-BCE1-4B1CE14A8D36}_is1" Then
Return True
EndIf
$j += 1
WEnd
Next
Return False
EndFunc ;==>_CheckOAPlugin
Func _CheckOFD()
Local $sKey
Local $sRegPath64 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Local $sRegPath32 = "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
If _RegKeyExists($sRegPath64, "增值税电子发票阅读器") Then
_CheckAndUpdateStatus($gLabel_Status[4], "OFD阅读器已安装", 0x008000)
GUICtrlSetState($aCheckboxes[4], $GUI_UNCHECKED)
ElseIf _RegKeyExists($sRegPath32, "增值税电子发票阅读器") Then
_CheckAndUpdateStatus($gLabel_Status[4], "OFD阅读器已安装", 0x008000)
GUICtrlSetState($aCheckboxes[4], $GUI_UNCHECKED)
Else
_CheckAndUpdateStatus($gLabel_Status[4], "OFD阅读器未安装", 0xFF0000)
GUICtrlSetState($aCheckboxes[4], $GUI_CHECKED)
EndIf
EndFunc ;==>_CheckOFD
Func _RegKeyExists($sRegPath, $sKeyToCheck)
Local $i = 1
While 1
Local $sKey = RegEnumKey($sRegPath, $i)
If @error Then ExitLoop
If $sKey = $sKeyToCheck Then
Return True
EndIf
$i += 1
WEnd
Return False
EndFunc ;==>_RegKeyExists
Func _CheckAndUpdateStatus($nLabelID, $sStatus, $nColor)
GUICtrlSetData($nLabelID, $sStatus)
GUICtrlSetColor($nLabelID, $nColor)
EndFunc ;==>_CheckAndUpdateStatus
ini配置文件:[SoftwareList]
Count=6
MandatoryCount=2
OptionalCount=4
[Software1]
Name=Flash插件
URL=http://xxx.exe
SaveAs=Flash.exe
Parameters=
Option=1
[Software2]
Name=新OA插件
URL=http://xxx.msi
SaveAs=OA.msi
Parameters=/qb /norestart
Option=0
[Software3]
Name=OFD阅读器
URL=http://xxx.exe
SaveAs=OFD.exe
Parameters=/NCRC /S
Option=1
[Software4]
Name=OFD阅读器4
URL=http://xxx.exe
SaveAs=OFD.exe
Parameters=/NCRC /S
Option=1
[Software5]
Name=OFD阅读器5
URL=http://xxx.exe
SaveAs=OFD.exe
Parameters=/NCRC /S
Option=0
[Software6]
Name=OFD阅读器6
URL=http://xxx.exe
SaveAs=OFD.exe
Parameters=/NCRC /S
Option=1
|