【发布时间】:2023-02-17 07:25:03
【问题描述】:
正如标题所说,如果可能的话,如何在事件发生后将 Powershell GUI 窗口置于另一个窗口之前?例如,我打开了 Firefox,Powershell GUI 在它后面运行,在 Powershell 内部发生某些事件后,它会弹出到 Firefox 前面吗?
【问题讨论】:
标签: powershell
正如标题所说,如果可能的话,如何在事件发生后将 Powershell GUI 窗口置于另一个窗口之前?例如,我打开了 Firefox,Powershell GUI 在它后面运行,在 Powershell 内部发生某些事件后,它会弹出到 Firefox 前面吗?
【问题讨论】:
标签: powershell
在 Windows 上,您可以使用 [Microsoft.VisualBasic.Interaction]::AppActivate() 通过进程 ID 重新激活您自己的进程的主窗口,如 automatic $PID variable 所示:
# Load the required assembly.
Add-Type -AssemblyName Microsoft.VisualBasic
# Launch a sample GUI application that will steal the focus
# (will become the foreground application).
Start-Process notepad.exe
# Wait a little.
Start-Sleep 3
# Now reactivate the main window of the current process.
[Microsoft.VisualBasic.Interaction]::AppActivate($PID)
警告:
其他进程窗口的编程激活是阻止默认情况下:
你可以允许通过 SystemParametersInfo WinAPI 函数无条件激活,通过将其SPI_SETFOREGROUNDLOCKTIMEOUT设置为0,如下所示——谨慎使用。
Add-Type -ErrorAction Stop -Namespace Util -Name WinApi -MemberDefinition @'
[DllImport("user32.dll", EntryPoint="SystemParametersInfo")]
public static extern bool SystemParametersInfo_Set_UInt32(uint uiAction, uint uiParam, UInt32 pvParam, uint fWinIni);
'@
if ([Util.WinApi]:: SystemParametersInfo_Set_UInt32(0x2001 <# SPI_SETFOREGROUNDLOCKTIMEOUT #>, 0, 0 <# timeout in ms. #>, 0 <# non-persistent #>)) {
"Set timeout to 0, for this session."
} else {
throw "Setting timeout failed."
}
【讨论】:
SetForegroundWindow() 的好替代品,因此可以避免 P/Invoke。在确定进程的“主窗口”后,它可能会调用SetForegroundWindow,因此它实际上只是闪烁任务栏按钮,而不是主动将窗口设置为前台。
ForegroundLockTimeout 注册表值是默认值,但 SystemParametersInfo() WinAPI 函数确实表明激活是允许,但我不知道设置在哪里(它是不是与开发者模式相关,在我的机器上是关闭的)。你有解释吗?
SystemParametersInfo() 实际查询了哪些注册表项。