虽然这个答案与 Selenium 无关,但我认为它可能会帮助其他人寻找这个问题的答案。
我以前遇到过这种情况,虽然不可能使用 Selenium 来“点击”一个 flash 按钮,但点击那个按钮并继续做你需要做的事情并不容易。
网页上的任何 Flash 电影都与任何其他窗口一样,只是不像任何其他元素那样易于访问,但如果您“足够低”,则可以枚举属于该浏览器实例的窗口并找到 Flash 窗口。
所以思路如下:
查找活动的浏览器实例(IE、FF、Chrome 等在本例中为 IE)
var ps = Process.GetProcessesByName("iexplore").Select(p => p.Id);
foreach (var handle in ps.SelectMany(EnumerateProcessWindowHandles))
{
GetChildWindows(handle);
if (_macromediaFound != false){break;}
}
列出它的所有子窗口(使用 Windows API 枚举 WindowsEx)
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
找到具有名为 MacromediaFlashPlayerActiveX 的 Window 的窗口(在 IE 中)
每次在步骤 1 列出的每个进程上找到子窗口时,前面的代码都会调用函数(方法)EnumWindow
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
StringBuilder message = new StringBuilder(1000);
SendMessage(handle, WmGettext, message.Capacity, message);
StringBuilder classN = new StringBuilder(1000);
GetClassName(handle, classN, classN.Capacity);
if (classN.ToString().Contains("MacromediaFlashPlayerActiveX"))
{ // continues below....
有了这些信息,您将获得窗口的 XY 位置,并且您需要找到正确的 XY 以单击屏幕上的按钮。
Thread.Sleep(2000); // this will allow any needed time to actually draw the flash on screen
Rectangle rect = new Rectangle();
GetWindowRect(handle, ref rect);
var oldPos = Cursor.Position;
Point clientPoint = new Point(rect.X + 20, rect.Y + 10); // In this particular Flash Movie the Upload File button is 20 points from x and 10 points from Y)
if (rect.X != 0 && rect.Y != 0)
{
Cursor.Position = new Point(clientPoint.X, clientPoint.Y);
}
向这些坐标发送点击事件
mouse_event(MouseEventfLeftdown, 0, 0, 0, UIntPtr.Zero);
mouse_event(MouseEventfLeftup, 0, 0, 0, UIntPtr.Zero);
Thread.Sleep(2000);
// Options but "clean" return the mouse to it's original position
Cursor.Position = oldPos;
发送点击后,查找 ClassName #32770 的窗口(至少在 IE 中)
hwndTmp = (IntPtr)FindWindow("#32770", "Text of the upload window");
从这里开始,继续该过程应该非常简单。
我知道这不是最干净的解决方案(您需要一个登录用户,并且还有一个屏幕可以从中获取坐标),但我知道有一个事实是,在某些情况下没有其他选择,您需要找到一个解决方案。
希望这可以帮助。