访问 Watin 新版本 2.1 中的帧时出错

本文关键字:出错 Watin 新版本 访问 | 更新日期: 2023-09-27 17:55:09

在新

版 Watin 2.1 中访问ie.Frames时会抛出以下错误

错误详细信息:无法使用已与其基础 RCW 分离的 COM 对象。

    System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.
   at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, Boolean& pfNeedsRelease)
   at mshtml.HTMLFrameElementClass.IHTMLElement_get_tagName()
   at WatiN.Core.Native.InternetExplorer.IEElement.get_TagName()
   at WatiN.Core.ElementTag.FromNativeElement(INativeElement nativeElement)
   at WatiN.Core.StaticElementFinder.CreateTagList(INativeElement nativeElement)
   at WatiN.Core.StaticElementFinder..ctor(DomContainer domcontainer, INativeElement nativeElement)
   at WatiN.Core.Element.InitElement(DomContainer domContainer, INativeElement nativeElement, ElementFinder elementFinder)
   at WatiN.Core.Element..ctor(DomContainer domContainer, INativeElement nativeElement)
   at WatiN.Core.Frame..ctor(DomContainer domContainer, INativeDocument frameDocument)
   at WatiN.Core.FrameCollection..ctor(DomContainer domContainer, INativeDocument htmlDocument)
   at WatiN.Core.Document.get_Frames()

请帮助我解决这个问题。

访问 Watin 新版本 2.1 中的帧时出错

我使用Praveen的建议修改了AllFramesProcessor的代码(见下文)。

在我这样做之前,我在 Watin 主干上做了一个 SVN 更新。 Jeroen 在 11 年 4 月 18 日进行了签入,修复了 WaitForFramesToComplete 以重试/等待加载主文档的问题。 仅靠Jeroen的修复并不能解决问题,但我相信正是该代码和修改后的AllFramesProcessor的结合使Wattin在框架问题上更加稳定。

public AllFramesProcessor(HTMLDocument htmlDocument)
{
    Elements = new List<INativeDocument>();
    _htmlDocument = htmlDocument;
    // Bug fix, trying to revert back to previous version
    // http://stackoverflow.com/questions/5882415/error-when-accessing-the-frames-in-watin-new-version-2-1
    //_iFrameElements = (IHTMLElementCollection)htmlDocument.all.tags("iframe");
    _iFrameElements = (IHTMLElementCollection)_htmlDocument.all.tags("frame");
    // If the current document doesn't contain FRAME elements, it then
    // might contain IFRAME elements.
    if (_iFrameElements.length == 0)
    {
        _iFrameElements = (IHTMLElementCollection)_htmlDocument.all.tags("iframe");
    }
}

可以通过访问ie.NativeDocument.Frames然后将ie和任何INativeElement对象传递给WatiN.Core.Element构造函数来解决此问题:

   Element ElementFromFrames(string elementId, IList<INativeDocument> frames)
   { 
     foreach(var f in frames)
      {
        var e=f.Body.AllDescendants.GetElementsById(elementId).FirstOrDefault();
        if (e != null) return new Element(ie ,e);
        if (f.Frames.Count > 0) 
         { var ret = ElementFromFrames(elementId, f.Frames);
           if (ret != null) return ret;
         }
      }     
     return null;
   }

来自 https://sourceforge.net/tracker/?func=detail&aid=3290877&group_id=167632&atid=843727

此问题似乎是由 AllFramesProcessor 类引起的。这Watin 1.3 中这个类的构造函数看起来像这样:

public AllFramesProcessor(DomContainer domContainer, HTMLDocument
htmlDocument)
{
elements = new ArrayList();
frameElements = (IHTMLElementCollection)
htmlDocument.all.tags(ElementsSupport.FrameTagName);
// If the current document doesn't contain FRAME elements, it then
// might contain IFRAME elements.
if (frameElements.length == 0)
{
frameElements = (IHTMLElementCollection)
htmlDocument.all.tags("IFRAME");
}
this._domContainer = domContainer;
this.htmlDocument = htmlDocument;
}

2.1 中的构造函数如下所示:

public AllFramesProcessor(HTMLDocument htmlDocument)
{
Elements = new List<INativeDocument>();
_htmlDocument = htmlDocument;
_iFrameElements =
(IHTMLElementCollection)htmlDocument.all.tags("iframe");
}

通过将"htmlDocument.all.tags("iframe")"更改为 "htmlDocument.all.tags("frame")"根据 Watin 1.3 构造函数此似乎可以解决此问题。不太确定为什么更改构造函数不过只是寻找iFrames。

最近我也遇到了这个问题,我首先按照Richard Guions(接受的)答案开始,只是为了详细说明一下,我做了以下工作:-

svn co https://watin.svn.sourceforge.net/svnroot/watin watin 

然后加载了"Watin/trunk/src/WatiN.sln"解决方案并重新编译了src,然后在我的项目中引用了新的Watin.core.dll。

低,看browser.Frame(Find.ByName("maincontent"));开始工作,我不需要在AllFrames代码上应用任何其他更改。所以我认为 svn 源已经更新以包含此更改