我有一个 Pwsh 脚本,其中的菜单可以执行几种不同的操作来帮助我完成日常工作。
对于其中一项操作,我使用 Start-Process 启动一个进程,只不过它聚焦于启动的窗口,但为了方便起见,我希望在启动后再次聚焦脚本而不是启动的进程。
我不想使用“PassThru”或“NoNewWindow”参数,因为我不想启动的进程在脚本中自行启动,也不想使用最小化的“WindowStyle”,因为无论如何这都会聚焦于启动的进程,也不想使用隐藏,因为我仍然需要在某处看到进程窗口。
我尝试过这种方法,似乎效果最好:
Start-Process -FilePath "MyProcessPath"
Start-Sleep -Seconds 1
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WinAp {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
"@
$p = Get-Process | Where-Object { $_.MainWindowTitle -like "*ScriptTitle*" -and $_.ProcessName -eq "powershell" }
$h = $p.MainWindowHandle
[void] [WinAp]::SetForegroundWindow($h)
[void] [WinAp]::ShowWindow($h, 1)
但不幸的是,它不起作用。它似乎对窗口做了一些操作,因为它在任务栏中闪烁,但并没有获得焦点。似乎虽然脚本是以管理员身份运行的,但它无法像管理员窗口那样获得焦点?
但是,对于脚本的另一部分,我这样做了:
$tempPath = [System.IO.Path]::GetTempFileName().Replace(".tmp", ".vbs")
$code = @'
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.AppActivate "App.exe"
WScript.Sleep 250
WshShell.SendKeys "{ENTER}"
'@
$code | Out-File $tempPath -Encoding ASCII
Start-Process "wscript.exe" $tempPath -Wait
Remove-Item $tempPath
它运行正常……它聚焦窗口,然后按下所需的键(尽管这部分在我目前的问题中不是必需的)。我试过我的脚本,但是……什么也没做。尤其是应用程序是用脚本启动的,所以我想管理员身份也能启动吧?所以我不明白为什么它有效,但脚本本身却不行。
谢谢你!