PowerShell Winforms脚本首次调用ShowDialog报空值表达式错误如何解决?
问题根因
你代码的执行顺序逻辑错误是核心问题:
$Form_HomePage.ShowDialog()是阻塞方法,运行后会一直停留在主窗体的消息循环,直到你关闭主窗体,这行之后的$Form_UserInformation定义代码才会执行- 首次运行时点「Start」按钮,
$Form_UserInformation还没被创建,属于空变量,调用方法就会抛出空引用错误 - 第二次运行脚本时,上一次运行时创建的
$Form_UserInformation变量还残留在PowerShell会话中,所以不会报错;但打包为EXE后每次运行都是全新会话,没有残留变量,所以必现崩溃
修复方案
- 调整代码顺序:所有窗体的创建逻辑全部放到
ShowDialog调用之前,确保用到窗体变量时已经完成初始化 - 调整点击事件逻辑:先隐藏主窗体,再显示第二个窗体,避免主窗体停留在前台
- 补充依赖加载和窗体关闭逻辑:补全Winform依赖程序集加载,同时添加第二个窗体关闭后的交互逻辑
修正后完整可运行代码如下:
# 加载Winform依赖程序集,避免部分环境运行报错 Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # 提前创建所有窗体 # User Information Form $Form_UserInformation = New-Object System.Windows.Forms.Form $Form_UserInformation.text = "New User Script" $Form_UserInformation.Size = New-Object System.Drawing.Size(400,400) $Form_UserInformation.FormBorderStyle = "FixedDialog" $Form_UserInformation.TopMost = $false $Form_UserInformation.MaximizeBox = $false $Form_UserInformation.MinimizeBox = $true $Form_UserInformation.ControlBox = "true" $Form_UserInformation.StartPosition = "CenterScreen" $Form_UserInformation.Font = "Segoe UI" # 补充第二个窗体关闭逻辑:关闭后自动回到主窗体 $Form_UserInformation.Add_FormClosed({ $Form_HomePage.Show() }) # HomePage Form $Form_HomePage = New-Object System.Windows.Forms.Form $Form_HomePage.text = "New User Script" $Form_HomePage.Size = New-Object System.Drawing.Size(400,400) $Form_HomePage.FormBorderStyle = "FixedDialog" $Form_HomePage.TopMost = $false $Form_HomePage.MaximizeBox = $false $Form_HomePage.MinimizeBox = $true $Form_HomePage.ControlBox = "true" $Form_HomePage.StartPosition = "CenterScreen" $Form_HomePage.Font = "Segoe UI" # Title label $label_HomeTitle = New-Object System.Windows.Forms.Label $label_HomeTitle.Location = New-Object System.Drawing.Size(47,8) $label_HomeTitle.Size = New-Object System.Drawing.Size(300,42) $label_HomeTitle.Font = New-Object System.Drawing.Font("Segoe UI",24,[System.Drawing.FontStyle]::Regular) $label_HomeTitle.TextAlign = "MiddleCenter" $label_HomeTitle.Text = "Kuehne & Nagel" $Form_HomePage.Controls.Add($label_HomeTitle) # Subheading label $label_HomeSubTitle = New-Object System.Windows.Forms.Label $label_HomeSubTitle.Location = New-Object System.Drawing.Size(50,60) $label_HomeSubTitle.Size = New-Object System.Drawing.Size(300,42) $label_HomeSubTitle.Font = New-Object System.Drawing.Font("Segoe UI",16,[System.Drawing.FontStyle]::Regular) $label_HomeSubTitle.TextAlign = "MiddleCenter" $label_HomeSubTitle.Text = "New User Script" $Form_HomePage.Controls.Add($label_HomeSubTitle) # Next button $button_HomeStart = New-Object System.Windows.Forms.Button $button_HomeStart.Location = New-Object System.Drawing.Size(75,200) $button_HomeStart.Size = New-Object System.Drawing.Size(240,32) $button_HomeStart.TextAlign = "MiddleCenter" $button_HomeStart.Text = "Start" $button_HomeStart.Add_Click({ # 先隐藏主窗体,再显示第二个页面 $Form_HomePage.Hide() [void] $Form_UserInformation.ShowDialog() }) $Form_HomePage.Controls.Add($button_HomeStart) # About button $button_About = New-Object System.Windows.Forms.Button $button_About.Location = New-Object System.Drawing.Size(75,250) $button_About.Size = New-Object System.Drawing.Size(240,32) $button_About.TextAlign = "MiddleCenter" $button_About.Text = "About" $button_About.Add_Click({ }) $Form_HomePage.Controls.Add($button_About) # Exit button $button_HomeExit = New-Object System.Windows.Forms.Button $button_HomeExit.Location = New-Object System.Drawing.Size(75,300) $button_HomeExit.Size = New-Object System.Drawing.Size(240,32) $button_HomeExit.TextAlign = "MiddleCenter" $button_HomeExit.Text = "Exit" $button_HomeExit.Add_Click({ $Form_HomePage.Close() }) $Form_HomePage.Controls.Add($button_HomeExit) # Show Form $Form_HomePage.Add_Shown({$Form_HomePage.Activate()}) [void] $Form_HomePage.ShowDialog()
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

