如何通过Powershell事件订阅者操作​​设置前景窗口 [英] How to set foreground Window from Powershell event subscriber action

查看:145
本文介绍了如何通过Powershell事件订阅者操作​​设置前景窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 FileSystemWatcher 实例在我的PoSh会话的后台运行,以监视文本文件的更改. PoSh事件订阅者将附加到此事件,并在触发时通过调用 Start-Process 启动控制台程序.该程序从当前前景窗口(我的PoSh控制台)窃取了焦点.从PoSh事件订阅者调用 SetForegroundWindow 将焦点返回到我的PoSh控制台不起作用. SwitchToThisWindow 大部分时间都可以正常工作,但是根据MSDN文档,不应使用它.

I have a FileSystemWatcher instance running in the background of my PoSh session watching for changes to text files. A PoSh event subscriber is attached to this event and, when fired, it launches a console program by calling Start-Process. This program steals de focus from the current foreground window (my PoSh console). Calling SetForegroundWindow from the PoSh event subscriber to return the focus to my PoSh console doesn't work. SwitchToThisWindow does work most of the time, but according to the MSDN docs, it shoulnd't be used.

在这种情况下,我可以防止启动过程窃取焦点或将其从事件订阅者重新设置为触发该事件之前的窗口吗?

Can I prevent Start-Process from stealing the focus in this situation or set it back from the event subscriber to the window that had it before this event is fired?

推荐答案

对我来说SetForegroundWindow效果很好.检查此代码:

For me SetForegroundWindow works well. Check this code:

Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class Tricks {
     [DllImport("user32.dll")]
     [return: MarshalAs(UnmanagedType.Bool)]
     public static extern bool SetForegroundWindow(IntPtr hWnd);
  }
"@
sleep -sec 2
$h = (Get-Process firefox).MainWindowHandle
[void] [Tricks]::SetForegroundWindow($h)
sleep -sec 2
$h = (Get-Process -id $pid).MainWindowHandle
[void] [Tricks]::SetForegroundWindow($h)

但是请注意,如果您托管PowerShell或使用例如控制台( http://sourceforge.net/projects/console/),然后MainWindowHandle是您的句柄主机程序. 因此,您需要[tricks]::SetForegroundWindow((Get-Process console).MainWindowHandle)代替(Get-Process -id $pid).MainWindowHandle.

But note that if you host PowerShell or use e.g. Console (http://sourceforge.net/projects/console/) then MainWindowHandle is the handle of your host program. So instead of (Get-Process -id $pid).MainWindowHandle you would need [tricks]::SetForegroundWindow((Get-Process console).MainWindowHandle).

带有计时器事件的示例:

Example with timer event:

$timer = New-Object Timers.Timer
$timer.Interval = 5000
$h = (Get-Process -id $pid).MainWindowHandle
$action = { 
    notepad; 
    sleep -sec 1;  # wait until the program starts (very simple approach)
    [Tricks]::SetForegroundWindow($h) }
Register-ObjectEvent $timer Elapsed -Action $action
$timer.Start()


否则,如果您运行的进程隐藏了窗口,则可以解决您的问题.


Otherwise if you run process that has its window hidden, it could solve your problem.

$ps = new-object system.diagnostics.processstartinfo 'notepad'
$ps.windowStyle = 'hidden'
[system.diagnostics.process]::Start($ps)

从msdn上有关流程的文档中摘录并更改的示例a>类

Example taken and altered from documentation on msdn about Process class

这篇关于如何通过Powershell事件订阅者操作​​设置前景窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆