I have the following two line code which will bring the respective window to the front that will help me take screenshots automatically. But the problem is that, sometimes, it works like a charm and sometimes it doesn't. And when I say it doesn't work, I don't mean that it is failing with any error message or warnings. Nothing happens. Just the code runs and the windows doesn't come to the front.
I would like to know if there is any hidden prerequisites for this snippet to run successfully? Should the window in question should be in any state before I run this code to bring that window upfront?
Here is the code:
[void][System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[Microsoft.VisualBasic.Interaction]::AppActivate("R")
I've had trouble using the Title-overload before. Also, a single change in the windows title will break
AppActivate(string Title)
.Does it work better with the
ProcessID
-overload? Ex.If you're using a COM-application, you need to get the process based on the
MainWindowHandle
, like this:Possibilities are that the program takes the control back as soon as powershell switches control to the desired program... Try to loop the activate until you take the screenshot...
Using AppActivate to bring out window title sometimes behaves indeed quite weird: no exception occurs and checking foreground window handle(using Win32 API: GetForegroundWindow) is accurate either, except that the window is still not showing anyway. To make sure the window does show before everything is completed, here is an alternative to using AppActivate. I tried using win32 API: "ShowWindowAsync" and "SetForegroundWindow" together, and check the return value to make sure. It works much more consistently than AppActivate.
(P.S. ShowWindowAsync: "Sets the show state of a window without waiting for the operation to complete.", according to Microsoft online docs). Code example: Assuming that the window title "R" already exists.
$IEtitles=get-process iexplore |?{$_.MainWindowTitle}|select -exp MainWindowTitle
foreach($IEtitle in $IEtitles) {
}
I simply iterate AppActivate several times.I know this is not beautiful solution. But it works for me.
sample code here.