好-首先,我已经解决了这个问题,我将概述问题以及解决方法。我的问题确实是看是否有人可以解释正在发生的事情以及为什么最终实现的解决方案行之有效,而原始代码却行不通。
我们正在通过REST API将一些第三方软件集成到我们的软件中。在初始身份验证步骤中,他们的软件为用户提供“登录”页面,然后他们可以通过该页面检索身份验证代码,然后在会话期间使用该代码。为了改善用户体验,我们将此“登录”页面加载到WebBrowser控件中,然后使用DOM查找用户需要将数据输入到其中的INPUT元素,将数据自动输入到这些元素中并提交表单。容易吧?
以下是原始代码的一些示例行,其中 wbLogin 是WebBrowser控件:
要获得用户应在其中输入电子邮件地址的INPUT元素
oEmail = wbLogin.Document.getElementsByName("email").item(0)
或
oEmail = wbLogin.Document.getElementById("LoginEmail")
要获取需要提交的表格:
If Not wbLogin.Document Is Nothing Then
If Not wbLogin.Document.Forms Is Nothing Then
If wbLogin.Document.Forms.length > 0 Then
oForm = wbLogin.Document.Forms.item(0)
End If
End If
End If
提交实际表格
oForm.Submit()
但是这里很奇怪。在我第一次加载对话框并完成所有这些操作后,所有这些操作都非常完美。但是第二次使用相同的页面加载相同的对话框时,我将收到NotSupportedError异常“ System.NotSupportedException:HRESULT的异常:0x800A01B6”,例如
这就是奇怪的地方。当我浏览代码时,我发现了
wbLogin.Document.getElementsByName("email")
失败了,我发现
wbLogin.Document.getelementsbyname("email")
成功。因此,我陷入了困境,在那里我开始编写代码,首先尝试第一个版本,然后尝试第二个版本。但是我很快发现这将在三次迭代中失败,然后
wbLogin.Document.GetElementsByName("email")
将会成功...或
wbLogin.Document.GETELEMENTSBYNAME("email")
类似地,oForm.Submit()将只工作一次,然后oForm.submit(),然后是oForm.SUBMIT(),但是每个变体只能工作一次。当然,重新启动应用程序将“清理状态”,但这在每个会话期间都会发生。
情况变得更糟。我为此类异常编写的代码越多,代码在其他地方开始失败的可能性就越大。并启动最疯狂的错误。在某些时候,我会得到这些返回DBNulls或Booleans的方法。但是我仍然坚持为越来越多的异常编码。 Try / Catch块到处都是,但是每当我尝试一件事情时,其他事情就会掉下来,或者其他事情会胡说八道。我正在撕头发。我尝试编写自己的DOM遍历代码,试图通过蛮力找到元素,但即使那样,也会在后续访问中引起错误。我最初的几行代码膨胀到超过500行,但我仍然远远没有找到解决方案。
很幸运,我终于找到了每次都能使用的解决方案
例如,要获取上述的INPUT字段,我现在执行以下操作:
Dim oDocType As System.Type = wbLogin.Document.GetType
Try
oEmail = oDocType.InvokeMember("getElementById", Reflection.BindingFlags.Default + Reflection.BindingFlags.InvokeMethod, Nothing, wbLogin.Document, {"LoginEmail"})
Catch
End Try
提交表格:
oForm.GetType().InvokeMember("submit", Reflection.BindingFlags.Default + Reflection.BindingFlags.InvokeMethod, Nothing, oForm, {})
所以我的问题是: