PowerShell Form窗口在powershell.exe与ISE下焦点获取行为差异疑问
PowerShell 不同宿主运行 Form 窗口焦点差异问题解答
差异原因
- PowerShell ISE 本身是基于 Windows Forms 构建的图形化宿主程序,运行时自带 Windows Forms 消息循环上下文,调用
ShowDialog()时,弹出的窗体会默认将 ISE 窗口识别为父窗口,符合模态窗口的默认行为,会自动抢占焦点。 - 传统 powershell.exe 是控制台宿主,没有内置 Windows Forms 的 UI 消息循环,调用
ShowDialog()时无法匹配到当前活动的 UI 父窗口,因此不会触发自动抢占焦点的逻辑。
解决方法
System.Windows.Forms.Form.ShowWithoutActivation 属性可实现窗口显示时不激活的效果,该属性为只读属性,需要通过继承 Form 类重写该属性的 Get 方法返回 $true,即可在所有 PowerShell 宿主中统一实现窗口弹出不抢占焦点的效果,修改后的代码如下:
Add-Type -AssemblyName System.Windows.Forms # 继承Form类重写ShowWithoutActivation属性 $customForm = Add-Type -PassThru -Name "NoActivateForm" -MemberDefinition @' protected override bool ShowWithoutActivation { get { return true; } } '@ -BaseClass [System.Windows.Forms.Form] $Form = $customForm::new() $Form.TopMost = $true $Form.ShowDialog()
重写属性后,窗口会保留置顶特性,且不会抢占当前活动窗口的输入焦点。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

