-->

Error when accessing the Frames in Watin new versi

2019-02-14 23:53发布

问题:

Below error is thrown when accessing the ie.Frames in new version of Watin 2.1

Error details: COM object that has been separated from its underlying RCW cannot be used.

    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()

Please help me out it in solving this.

回答1:

I modified the code for AllFramesProcessor using Praveen's suggestion (see below).

Before I did this, I did an SVN update on the Watin trunk. Jeroen made a checkin on 4/18/11 that fixed an issue around WaitForFramesToComplete to retry/wait loading the main document. Jeroen's fix alone didn't solve the problem, but I believe it's the combination of that code and the modified AllFramesProcessor that made Watin more stable around the Frames issue.

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


回答2:

You can work around this by accessing ie.NativeDocument.Frames and then passing ie and any INativeElement objects to the WatiN.Core.Element constructor:

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


回答3:

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

This problem seems to be caused by the AllFramesProcessor class. The constructor for this class in Watin 1.3 looked like this:

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

The constructor in 2.1 looks like this:

public AllFramesProcessor(HTMLDocument htmlDocument)
{
Elements = new List<INativeDocument>();
_htmlDocument = htmlDocument;

_iFrameElements =
(IHTMLElementCollection)htmlDocument.all.tags("iframe");
}

By changing the "htmlDocument.all.tags("iframe")" to be "htmlDocument.all.tags("frame")" as per the Watin 1.3 constructor this seems to resolve this issue. Not quite sure why the constructor was changed to just look for iFrames though.



回答4:

Recently I also encountered this problem and I started by following Richard Guions (accepted) answer and just to elaborate a little on that I did the following:-

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

and then loaded the "Watin/trunk/src/WatiN.sln" solution and recompiled the src, then referencing that new Watin.core.dll in my project.

Low and behold the browser.Frame(Find.ByName("maincontent")); started working and I did not need to apply any other changes to the AllFrames code. So I think that the svn source has already been updated to include this change



标签: c# watin