PowerShell实现WinForm复选框勾选软件自动安装方法
说明:本文所列更新后的代码现已可正常运行!!
问题描述
我基于PowerShell + WinForms开发了图形化软件批量安装工具,核心逻辑是从CSV文件读取软件清单动态生成复选框,目前窗体基础展示功能正常,但始终无法实现勾选软件的自动安装逻辑,需求规则如下:
- 若某软件(如FileZilla)被勾选,则程序自动读取CSV中该软件对应的安装路径启动安装程序
- 若未被勾选则直接跳过,继续遍历下一个软件(如Firefox)执行相同判断
- 遍历完所有条目后,完成全部选中软件的安装
目前没有检索到足够的参考资料完成复选框状态与对应安装路径的关联匹配,现有实现代码如下:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.Application]::EnableVisualStyles() $Form = New-Object System.Windows.Forms.Form $Form.Size = New-Object System.Drawing.Size(600,700) $Form.text ="Software Installer" ############################################## Start group boxes $groupBox = New-Object System.Windows.Forms.GroupBox $groupBox.Location = New-Object System.Drawing.Size(20,20) $groupBox.text = "Availabe Software to Install:" $Form.Controls.Add($groupBox) $Checkboxes += New-Object System.Windows.Forms.CheckBox $Checkboxes.Location = New-Object System.Drawing.Size(10,20) $Button1 = New-Object system.Windows.Forms.Button $Button1.text = "Install" $Button1.width = 60 $Button1.height = 30 $Button1.location = New-Object System.Drawing.Point(230,30) $Button1.Font = 'Microsoft Sans Serif,10' $apps = [PSCustomObject]@{ Name = '' Path = '' PreTransfer = '' } $apps = Import-Csv -Path c:\temp\applist.csv $groupBox.Controls.Add($Button1) $Checkboxes = @() $y = 20 foreach ($a in $apps) { $Checkbox = New-Object System.Windows.Forms.CheckBox $Checkbox.name = $a.Name $Checkbox.Text = $a.Name $Checkbox.Location = New-Object System.Drawing.Size(10,$y) $y += 30 $groupBox.Controls.Add($Checkbox) $Checkboxes += $Checkbox } $groupBox.size = New-Object System.Drawing.Size(400,(40*$checkboxes.Count)) //what I was trying to get to look at each box but couldn't figure it out. $Button1.Add_Click({ foreach ($i in $Checkboxes){ if ($i.checked -eq $true) { Start-Process $i.AccessibleDescription } } }) $form.ShowDialog()| Out-Null
修复方案
代码跑不通的核心原因很明确:
- 生成复选框时没有把对应软件的安装路径和控件做绑定,点击安装时自然拿不到要启动的安装包路径
- 开头多写了一行冗余的复选框初始化代码,会干扰控件布局
- 安装按钮位置写死,软件条目多了会被复选框挡住;还用了C语言风格的
//注释,PowerShell不识别会直接触发语法错误
改法非常简单:WinForms所有控件都自带Tag属性,专门用来存储和控件关联的自定义数据,生成每个软件对应的复选框时,直接把CSV里读出来的安装路径存到Tag属性里即可。点击安装时遍历所有复选框,判断为选中状态就把Tag里存的路径取出来传给Start-Process启动,顺便把按钮位置挪到所有复选框下方,适配动态生成的条目高度即可。
修复后可直接运行的完整代码:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.Application]::EnableVisualStyles() $Form = New-Object System.Windows.Forms.Form $Form.Size = New-Object System.Drawing.Size(600,700) $Form.Text = "Software Installer" # 初始化软件列表分组框 $groupBox = New-Object System.Windows.Forms.GroupBox $groupBox.Location = New-Object System.Drawing.Size(20,20) $groupBox.Text = "Available Software to Install:" $Form.Controls.Add($groupBox) # 读取CSV软件清单,确保CSV包含Name、Path两个必填列 $apps = Import-Csv -Path c:\temp\applist.csv $Checkboxes = @() $y = 20 # 动态生成每个软件对应的复选框 foreach ($a in $apps) { $Checkbox = New-Object System.Windows.Forms.CheckBox $Checkbox.Name = $a.Name $Checkbox.Text = $a.Name $Checkbox.Location = New-Object System.Drawing.Size(10,$y) # 将当前软件的安装路径绑定到复选框的Tag属性 $Checkbox.Tag = $a.Path $groupBox.Controls.Add($Checkbox) $Checkboxes += $Checkbox $y += 30 } # 动态计算分组框高度,适配所有复选框条目 $groupBox.Size = New-Object System.Drawing.Size(400, ($y + 60)) # 初始化安装按钮,位置放在所有复选框下方 $Button1 = New-Object system.Windows.Forms.Button $Button1.Text = "Install" $Button1.Width = 60 $Button1.Height = 30 $Button1.Location = New-Object System.Drawing.Point(230, $y + 10) $Button1.Font = 'Microsoft Sans Serif,10' $groupBox.Controls.Add($Button1) # 安装按钮点击逻辑 $Button1.Add_Click({ foreach ($cb in $Checkboxes){ if ($cb.Checked -eq $true) { # 读取复选框Tag中存储的安装路径启动安装 Start-Process -FilePath $cb.Tag } } }) $form.ShowDialog() | Out-Null
使用前请确认c:\temp\applist.csv格式符合要求,示例CSV内容如下:
Name,Path,PreTransfer FileZilla,"C:\Installer\FileZilla_3.60.2_win64-setup.exe", Firefox,"C:\Installer\Firefox Setup 115.0.exe", 7-Zip,"C:\Installer\7z2301-x64.exe",
如果需要实现静默安装,给Start-Process追加对应安装包的静默参数即可,比如MSI格式安装包可以追加参数 -ArgumentList "/qn /norestart"。
内容的提问来源于stack exchange,提问作者Jonathan Bowley
相关产品推荐
相关产品推荐

