我有以下两个行代码,它们将相应的窗口放到前面,这将帮助我自动截取屏幕截图。但问题在于,有时它会像魅力一样,有时则不然。当我说它不起作用时,我并不是说它失败了任何错误信息或警告。什么都没发生。只是代码运行,窗口没有出现在前面。
我想知道此代码段是否有任何隐藏的先决条件才能成功运行?在我运行此代码之前,有问题的窗口是否应该处于任何状态才能使该窗口显示出来?
以下是代码:
[void][System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[Microsoft.VisualBasic.Interaction]::AppActivate("R")
答案 0 :(得分:2)
我以前在使用Title-overload时遇到了麻烦。此外,Windows标题中的单个更改将中断AppActivate(string Title)
。
使用ProcessID
- 重载会更好吗?实施例
$excelpid = (Get-Process excel).ID
[Microsoft.VisualBasic.Interaction]::AppActivate($excelpid)
如果您正在使用COM应用程序,则需要根据MainWindowHandle
获取流程,如下所示:
[void][System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
#start excel
$excel = New-Object -ComObject excel.application
#make excel visible
$excel.Visible = $true
#get pid from windows handle
$excelpid = (Get-Process | Where-Object { $_.MainWindowHandle -eq $excel.Hwnd }).Id
#Activate window
[Microsoft.VisualBasic.Interaction]::AppActivate($excelpid)
答案 1 :(得分:0)
可能的是,一旦powershell切换控制到所需的程序,程序就会取回控制权...尝试循环激活,直到你截取屏幕截图...
答案 2 :(得分:0)
我只是多次迭代AppActivate。我知道这不是很好的解决方案。但它对我有用。
示例代码。
for ($i = 1; $i -lt 5; $i++)
{
[Microsoft.VisualBasic.Interaction]::AppActivate("R")
}
答案 3 :(得分:0)
$ IEtitles =获取进程iexplore |?{$ _。MainWindowTitle} |选择-exp MainWindowTitle
foreach($ IEtitles中的$ IEtitle) {
Add-Type -AssemblyName Microsoft.VisualBasic
[Microsoft.VisualBasic.Interaction]::AppActivate("$IEtitle") | Out-Null
}
答案 4 :(得分:0)
使用AppActivate带出窗口标题有时确实确实很奇怪:没有异常发生,并且检查前景窗口句柄(使用Win32 API:GetForegroundWindow)也是准确的,除了窗口仍然不显示。 为确保在所有操作完成之前窗口确实显示,这里是使用AppActivate的替代方法。我尝试使用win32 API:“ ShowWindowAsync”和“ SetForegroundWindow”一起使用,并检查返回值以确保。它比AppActivate更加一致。
(P.S。ShowWindowAsync:“设置窗口的显示状态,而无需等待操作完成。”,根据Microsoft online docs)。 代码示例:假设窗口标题“ R”已经存在。
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class SFW {
[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 ShowWindowAsync(IntPtr hWnd, int nCmdShow);
}
"@
$Target_Title="R"
$hwnd =(Get-Process | Where-Object { $_.MainWindowTitle -eq $Target_Title } ).MainWindowHandle
Do
{
try
{
$r1=[SFW]::ShowWindowAsync($hwnd, 3)
$r2=[SFW]::SetForegroundWindow($hwnd)
}
catch
{
Write-Host "Error activating! Press any key to exit!"
cmd /c pause | out-null
exit
}
}while(($r1 -or $r2) -eq $false)
答案 5 :(得分:0)
$PROCESS = 'WINWORD'
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate((Get-Process $PROCESS).ID)
打开Microsoft Word进行测试。