如何用PowerShell创建MSI提取器?脚本运行报错求助
解决PowerShell中System.Windows.Forms控件找不到的报错问题
问题原因
你的脚本在PowerShell ISE中能正常运行,但普通PowerShell控制台执行时报错,核心原因是:PowerShell ISE会自动加载System.Windows.Forms程序集,而普通PowerShell控制台默认不会加载,导致创建OpenFileDialog和FolderBrowserDialog时提示找不到对应类型。
解决方案
1. 手动加载Windows Forms程序集
在脚本最开头添加代码,强制加载所需的程序集:
Add-Type -AssemblyName System.Windows.Forms
2. 处理用户取消对话框的情况
若用户在文件/文件夹选择对话框中点击「取消」,脚本应终止执行,避免后续msiexec命令因空参数报错。
3. 优化变量与逻辑
避免重复使用$Out变量,改用清晰的变量名区分不同对话框的返回结果;同时检查用户是否确实选择了文件和输出目录。
修改后的完整脚本
# 手动加载System.Windows.Forms程序集 Add-Type -AssemblyName System.Windows.Forms # 选择MSI文件 $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ InitialDirectory = [Environment]::GetFolderPath('Desktop') Filter = 'Windows Packages (*.msi)|*.msi' Title = "选择要提取的MSI文件" } $fileDialogResult = $FileBrowser.ShowDialog() # 用户取消选择则退出 if ($fileDialogResult -ne [System.Windows.Forms.DialogResult]::OK) { Write-Host "已取消选择MSI文件,脚本终止" exit } # 选择输出目录 $FolderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog -Property @{ Description = "选择MSI提取输出目录" ShowNewFolderButton = $true # 允许创建新文件夹 } $folderDialogResult = $FolderBrowser.ShowDialog() # 用户取消选择则退出 if ($folderDialogResult -ne [System.Windows.Forms.DialogResult]::OK) { Write-Host "已取消选择输出目录,脚本终止" exit } # 执行MSI提取(路径加引号避免空格问题) msiexec /a $FileBrowser.FileName /qb TARGETDIR="$($FolderBrowser.SelectedPath)" # 显示提示弹窗 $Shell = New-Object -ComObject "WScript.Shell" $null = $Shell.Popup("提取完成后,若程序需要从Shell(CMD/PowerShell)运行,请将其添加到系统Path中: 1. 搜索并打开「控制面板」 2. 依次选择「用户账户」→「用户账户」→「更改我的环境变量」 3. 选中「Path」变量,点击「编辑」 4. 添加程序所在路径(通常是根目录或bin目录),点击「确定」保存 5. 重启所有已打开的Shell窗口生效", 0, "MSI提取器提示", 0)
关键修改说明
- 开头添加
Add-Type -AssemblyName System.Windows.Forms:确保普通PowerShell控制台能识别Windows Forms控件类型 - 增加对话框结果判断:用户取消操作时直接退出脚本,避免无效执行
- 给
TARGETDIR参数加引号:解决路径包含空格时的命令执行错误 - 修正原脚本拼写错误:
Enviorment改为Environment,优化提示文本可读性
内容的提问来源于stack exchange,提问作者kernaltrap
相关产品推荐
相关产品推荐

