我也遇到了同样的问题,用谷歌搜索了很多,但没有找到可行的解决方案。超时解决方案不适用于我的情况。最后,似乎真正有效的唯一方法是使用全局钩子。
更多关于hook的信息,请参考这篇优秀的帖子:Global keyboard capture in C# application
所以,在上面链接中的钩子处理代码中,添加如下内容:
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
if (vkCode == 121) //F10 key
{
try
{
UnhookWindowsHookEx(_hookID);//avoid ESC key to be captured
SetForegroundWindow(_handle);
SendKeys.Send("{ESC}");
_hookID = SetHook(_proc);
}
catch (Exception ex)
{
}
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
相关代码如下:
using System.Windows.Automation; //you need to reference UIAutomationClient and UIAutomationTypes
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
private IntPtr _handle;
//I forget where I got the code of the function below, probably also from stackoverflow. Thanks to the original author!
private IntPtr getIntPtrHandle(IWebDriver driver, int timeoutSeconds = 30)
{
var end = DateTime.Now.AddSeconds(timeoutSeconds);
while (DateTime.Now < end)
{
// Searching by AutomationElement is a bit faster (can filter by children only)
var ele = AutomationElement.RootElement;
foreach (AutomationElement child in ele.FindAll(TreeScope.Children, Condition.TrueCondition))
{
if (!child.Current.Name.Contains(driver.Title)) continue;
return new IntPtr(child.Current.NativeWindowHandle); ;
}
}
return IntPtr.Zero;
}
也把 _handle = getIntPtrHandle(webdriver);在你的 webdriver.Navigate().GoToUrl() 语句之前的某个地方。
我测试了上述内容。执行 GoToUrl 后,在某处按 F10(有时两次),页面停止加载。