JLutz

Hi all,

I have a question about thread synchronization and UI automation.

Say I have a GUI application and an automation program similar to the one in the TreeWalker sample in the SDK documentation. Now say that in my automation program, I start up the GUI app by using the methods in the Process class.

My question is this: What is the best way to programmatically go about determining when my GUI app is done loading its UI so that I can begin the automation Essentially, how do I stall the automation client until just the right time

I tried doing Thread.Sleep for an arbitrary amount of time, but I want to find a more deterministic (and less touchy) solution.

Moreover, I tried the Process.WaitForInputIdle method(because I think I saw something in the SDK that recommended that; maybe I was mistaken), but that didn't seem to work. Right now my GUI app is non-WPF, so I was wondering if that's maybe a potential cause for this method not working (if I am indeed using it correctly).

Thanks in advance.

- JDL



Re: Microsoft UI Automation Thread Synchronization between Automation Client and UI Program

Peter Donnelly - MSFT

Thread.Sleep might be the best all-round solution. At present, WaitForInputIdle only works with Win32 apps.




Re: Microsoft UI Automation Thread Synchronization between Automation Client and UI Program

David S L

Is there any more information on this I am looking for a more reliable solution then Thread.Sleep to sync with the application.

Thanks,
David





Re: Microsoft UI Automation Thread Synchronization between Automation Client and UI Program

Nick Asseloos

Hi David,

I needed something similar and this is what I came up with. It works for our applications and I haven't had any problems with it. Hope this fits your needs.

private static IntPtr ExecuteProcess(string fileName, int startTimeout)
{
Process process = new Process();
process.StartInfo.FileName = fileName;
process.StartInfo.WorkingDirectory =
Path.GetDirectoryName(fileName);
process.Start();

int timeoutCounter = 0;
int processId = 0;
IntPtr windowHandle = IntPtr.Zero;

//Wait untill the foregroundwindow is the one of our application
//We do this by getting the process id of the process we started and comparing it
//with the process id of the window that is on the foreground.

while (processId != process.Id)
{
timeoutCounter++;
if (timeoutCounter == 15)
break;

windowHandle = NativeMethods.GetForegroundWindow();
NativeMethods.GetWindowThreadProcessId(windowHandle, out processId);
Thread.Sleep(1000);
}
process.Dispose();
return windowHandle;
}

There are the declarations of the win32 api's:
[
DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out int lpwdProcessID);

Grtz,
Nick





Re: Microsoft UI Automation Thread Synchronization between Automation Client and UI Program

David S L

Hi Nick,

Thanks for your response. I need to be able to detect when the application is finished processing input as well as when it is finished loading. I recently came across another method that I think will work.

A window pattern hase the property WindowInteractionState, which appears to return ReadyForUserInteraction when it is not processing input and Running when it is. (It also returns Running when a modal dialog is up.)

I believe that following loop will wait for the application to be in an idle state. It needs timeout logic, or else will run forever if the application stops responding.


WindowPattern mMainWindow;
//This is set to the control pattern for the main window of the app

while (mMainWindow.Current.WindowInteractionState != WindowInteractionState.ReadyForUserInteraction)
{//Wait
}

Thanks,
David





Re: Microsoft UI Automation Thread Synchronization between Automation Client and UI Program

David S L

Apparently the above method I described works great when running under windows XP, but now that we have started testing on windows vista it no longer runs properly.

So, once again I am trying to get some information on how to synchronize my applications and my tests. Process.WaitForInputIdle() still does not work in vista, and the above workaround does not work in vista either. Is there any other way to synchronize to an application properly

Thanks,
David