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

时间:2011-05-04 11:06:41

标签: c# watin

在新版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()

请帮我解决这个问题。

4 个答案:

答案 0 :(得分:4)

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

在我这样做之前,我在Watin主干上做了一个SVN更新。 Jeroen于4/18/11进行了检查,修复了WaitForFramesToComplete周围的问题,以重试/等待加载主文档。单凭Jeroen的修复并没有解决问题,但我相信这是代码和修改后的AllFramesProcessor的组合,使得Watin在Frames问题上更加稳定。

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");
    }
}

答案 1 :(得分:2)

您可以通过访问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;
   }

答案 2 :(得分:2)

来自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。

答案 3 :(得分:0)

最近我也遇到了这个问题,我开始关注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源已经更新以包含此更改