如何在不窃取焦点的情况下执行powershell脚本?

时间:2015-04-07 16:11:01

标签: powershell

我创建了一个powershell脚本,它使用GetForegroundWindow()来识别哪个Window是当前关注的Window。不幸的是,当执行powershell脚本时(通过Windows任务计划程序或热键),脚本会窃取当前前台应用程序的焦点;错误地使用Powershell窗口本身作为Foreground应用程序,而不是预期的前台应用程序。

我甚至尝试使用PS2EXE“-noconsole”设置创建EXE;但是,脚本仍然不起作用。

有人可以建议一种方法来执行这个脚本而不改变当前前景窗口的焦点吗?

我的脚本代码在测试期间有效(仅当我添加“Start-Sleep -s 5”时;并且,使用alt-tab手动窃取焦点,以便脚本识别正确的前景窗口。

Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class Tricks {
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
}
"@


function Set-WindowStyle {
param(
    [Parameter()]
    [ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE',
                 'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED',
                 'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')]
    $Style = 'SHOW',
    [Parameter()]
    $MainWindowHandle = (Get-Process -Id $pid).MainWindowHandle
)
    $WindowStates = @{
        FORCEMINIMIZE   = 11; HIDE            = 0
        MAXIMIZE        = 3;  MINIMIZE        = 6
        RESTORE         = 9;  SHOW            = 5
        SHOWDEFAULT     = 10; SHOWMAXIMIZED   = 3
        SHOWMINIMIZED   = 2;  SHOWMINNOACTIVE = 7
        SHOWNA          = 8;  SHOWNOACTIVATE  = 4
        SHOWNORMAL      = 1
    }
    Write-Verbose ("Set Window Style {1} on handle {0}" -f $MainWindowHandle, $($WindowStates[$style]))

    $Win32ShowWindowAsync = Add-Type -memberDefinition @"
    [DllImport("user32.dll")]
    public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
"@ -name "Win32ShowWindowAsync" -namespace Win32Functions -passThru

    $Win32ShowWindowAsync::ShowWindowAsync($MainWindowHandle, $WindowStates[$Style]) | Out-Null
}


$a = [tricks]::GetForegroundWindow()

$title = get-process | ? { $_.mainwindowhandle -eq $a }
$title2 = $title | select -ExpandProperty ProcessName

if ($title2 -eq 'Kodi'){

    Set-WindowStyle MINIMIZE $a;
    if (Get-Process -Name Yatse2) {(Get-Process -Name Yatse2).MainWindowHandle | foreach { Set-WindowStyle MINIMIZE $_ }}

} ELSE {

    $title.CloseMainWindow()
}

2 个答案:

答案 0 :(得分:0)

我知道这个问题很旧,但是我花了很多时间试图弄清楚如何从当前窗口中脱颖而出,并找到了一些信息,因此希望对以后的读者有所帮助。

最简单的解决方案是从Powershell脚本中实际模拟Alt+Tab按键,而不必自己进行。以下代码来自this StackOverflow answer

[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
[System.Windows.Forms.SendKeys]::SendWait("%{TAB}")
# Retrieve the window handles...

......,其中%代表Alt修饰符,{TAB}被解释为Tab键。

答案 1 :(得分:-1)

  1. Create task that can be run on demand in Task Scheduler and executes your powershell script
  2. Make sure it is set to be run whether user is logged on or not
  3. Create a shortcut that starts the task

That allows your script to be run without visible window