views:

72

answers:

3

I'm using automation to test an application, but sometimes I want to start the application via a batch file. When I run "process.WaitForInputIdle(100)" I get an error:

"WaitForInputIdle failed. This could be because the process does not have a graphical interface."

How can I tell if the process has a graphical interface or not?

+1  A: 

See Environment.UserInteractive. That will identify whether the process has an interface at all, e.g. services are not user interactive.

You could also look at Process.MainWindowHandle which will tell you whether there is a graphical interface.

A combination of these two checks should cover all the possibilities.

Paul Ruane
@0xA3: The Process.MainWindowHandle (which I added as an edit whilst you wrote your comment) could be used to do this.
Paul Ruane
Unfortunately batch files appear to be user interactive (this returns "true" for both the batch file and the window).
Lunivore
When you say the Process.MainWindowHandle could be used to do this - how? Mind putting it in another answer?
Lunivore
if Process.MainWindowHandle == IntPtr.Zero it has no main window
Bear Monkey
Environment.UserInteractive is for the current process.
Bear Monkey
Doh, thanks @Bear Monkey - of course it is. Also for the idea of the MainWindowHandle, will give that a try.
Lunivore
Okay, this is the best answer I have so far. Doesn't solve all my problems, but sorts this one. Thanks!
Lunivore
@Lunivore: no problem.
Paul Ruane
A: 

You can simply try and catch the exception:

Process process = ...
try
{
    process.WaitForInputIdle(100);
}
catch (InvalidOperationException ex)
{
    // no graphical interface
}
0xA3
Yes, I can... for some reason this seems ugly to me though. Most decent libraries and APIs usually a way of determining whether an operation you're about to perform is valid or not. Microsoft usually provide this. If you don't mind I'll wait a day, see if anyone else has any ideas.
Lunivore
I agree, its quite ugly to use exceptions like this
Bear Monkey
@Lunivore, @Bear Monkey: It seems to me to be an exception somewhere in between a [vexing exception and an exogenous exception](http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx). To avoid the exception being thrown you could P/Invoke the `WaitForInputIdle` function.
0xA3
@Bear Monkey: Good point, though in this specific case you probably won't get any useful information. The [`WaitForInputIdle`](http://msdn.microsoft.com/en-us/library/ms687022%28VS.85%29.aspx) function called under the hood simply returns `WAIT_FAILED` in any of the four error cases.
0xA3
@0xA3 yes your right. I thought it used HRESULTS but it doesn't. I deleted my post before you replied when I realised my mistake.
Bear Monkey
A: 

I was think along the lines of this, Still ugly but trys to avoid exceptions.

Process process = ...

bool hasUI = false;

if (!process.HasExited)
{
    try
    {
        hasUI = process.MainWindowHandle != IntPtr.Zero;
    }
    catch (InvalidOperationException)
    {
        if (!process.HasExited)
            throw;
    }
}

if (!process.HasExited && hasUI)
{

    try
    {
        process.WaitForInputIdle(100);
    }
    catch (InvalidOperationException)
    {
        if (!process.HasExited)
            throw;
    }
}
Bear Monkey