我正在使用自动化来测试应用程序,但有时我想通过批处理文件启动应用程序。当我运行“process.WaitForInputIdle(100)”时出现错误:
“WaitForInputIdle 失败。这可能是因为进程没有图形界面。”
如何判断进程是否有图形界面?
我正在使用自动化来测试应用程序,但有时我想通过批处理文件启动应用程序。当我运行“process.WaitForInputIdle(100)”时出现错误:
“WaitForInputIdle 失败。这可能是因为进程没有图形界面。”
如何判断进程是否有图形界面?
请参阅Environment.UserInteractive。这将识别进程是否有接口,例如服务不是用户交互的。
您还可以查看Process.MainWindowHandle,它会告诉您是否有图形界面。
这两项检查的组合应涵盖所有可能性。
您可以简单地尝试捕获异常:
Process process = ...
try
{
process.WaitForInputIdle(100);
}
catch (InvalidOperationException ex)
{
// no graphical interface
}
我是这样想的,仍然很丑,但尽量避免例外。
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;
}
}
除了MainWindowHandle
检查之外,还可以枚举进程线程并检查它们中的任何一个是否通过 P/Invokes 引用可见窗口。这似乎可以很好地捕捉第一次检查遗漏的任何窗口。
private Boolean isProcessWindowed(Process externalProcess)
{
if (externalProcess.MainWindowHandle != IntPtr.Zero)
{
return true;
}
foreach (ProcessThread threadInfo in externalProcess.Threads)
{
IntPtr[] windows = GetWindowHandlesForThread(threadInfo.Id);
if (windows != null)
{
foreach (IntPtr handle in windows)
{
if (IsWindowVisible(handle))
{
return true;
}
}
}
}
return false;
}
private IntPtr[] GetWindowHandlesForThread(int threadHandle)
{
results.Clear();
EnumWindows(WindowEnum, threadHandle);
return results.ToArray();
}
private delegate int EnumWindowsProc(IntPtr hwnd, int lParam);
private List<IntPtr> results = new List<IntPtr>();
private int WindowEnum(IntPtr hWnd, int lParam)
{
int processID = 0;
int threadID = GetWindowThreadProcessId(hWnd, out processID);
if (threadID == lParam)
{
results.Add(hWnd);
}
return 1;
}
[DllImport("user32.Dll")]
private static extern int EnumWindows(EnumWindowsProc x, int y);
[DllImport("user32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
[DllImport("user32.dll")]
static extern bool IsWindowVisible(IntPtr hWnd);