在IE流程

时间:2015-12-04 10:35:51

标签: c# winforms pinvoke

我有一个多线程UI测试工具,可以启动Internet Explorer实例。我想找到一个使用PInvoke API的javascript警告框。

在全球范围内找到它可以正常工作:

IntPtr globalAlertHwnd = Pinvoke.FindWindow("#32770", "Message from webpage");

但是,由于我并行运行多个IE实例,因此我希望根据其IE父目标来定位特定的警告框。

我也可以在全球指针中找到它:

IntPtr desktopHwnd = Pinvoke.GetDesktopWindow();
List<IntPtr> allDesktopChilds = Pinvoke.GetChildWindows(desktopHwnd).ToList();

bool match1 = allDesktopChilds.Any(hwnd => hwnd == globalAlertHwnd); // true

但是一旦我使用IE进程,我找不到它。 mainWindowHnadle是IE的窗口句柄。

List<IntPtr> ieChildren = Pinvoke.EnumerateProcessWindowHandles(mainWindowHnadle).ToList();
bool match2 = ieChildren.Any(hwnd => hwnd == globalAlertHwnd); // false

这就是EnumerateProcessWindowHandles的样子:

public static IEnumerable<IntPtr> EnumerateProcessWindowHandles(IntPtr hwnd)
{
    List<IntPtr> handles = new List<IntPtr>();
    uint processId;
    GetWindowThreadProcessId(hwnd, out processId);

    foreach (ProcessThread thread in Process.GetProcessById((int)processId).Threads)
    {
        EnumThreadWindows(thread.Id, (parentHwnd, lParam) =>
        {
            handles.Add(parentHwnd);

            List<IntPtr> childHwnds = GetChildWindows(parentHwnd);
            handles.AddRange(childHwnds);

            return true;
        }, IntPtr.Zero);
    }

    return handles;
}

public static List<IntPtr> GetChildWindows(IntPtr parent)
{
    List<IntPtr> result = new List<IntPtr>();
    GCHandle listHandle = GCHandle.Alloc(result);
    try
    {
        Win32Callback childProc = new Win32Callback(EnumWindow);
        EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
    }
    finally
    {
        if (listHandle.IsAllocated)
            listHandle.Free();
    }
    return result;
}

我知道EnumChildWindows()得到所有孩子,而不仅仅是顶层(由我的第二个例子验证)。

我验证了一个IE线程中存在警报框及其OK按钮。 Spy ++截图:

enter image description here

我错过了什么?此方法适用于Firefox和Chrome。

更新

似乎出现此问题是因为IE为主窗口创建了一个进程,并为每个选项卡创建了另一个进程。我必须考虑如何基于此获取其他进程。

1 个答案:

答案 0 :(得分:0)

通过强制IE为每个实例创建单个进程来解决:

TabProcGrowth中创建或更新注册表项HKEY_CURRENT_USER\Software\MicrosoftInternet Explorer\Main。它应该是REG_DWORD 32位,值为0.