在 Watin 新版本 2.1 中访问框架时出错

发布于 2024-11-05 07:29:10 字数 1226 浏览 0 评论 0原文

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

请帮助我解决这个问题。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

巷雨优美回忆 2024-11-12 07:29:10

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

在执行此操作之前,我对 Watin 主干进行了 SVN 更新。 Jeroen 于 2011 年 4 月 18 日进行了签入,解决了围绕 WaitForFramesToComplete 重试/等待加载主文档的问题。仅 Jeroen 的修复并没有解决问题,但我相信正是该代码和修改后的 AllFramesProcessor 的组合使 Watin 在框架问题上更加稳定。

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

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");
    }
}
自由范儿 2024-11-12 07:29:10

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

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

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;
   }
过潦 2024-11-12 07:29:10

来自 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 构造函数
似乎可以解决这个问题。不太清楚为什么构造函数被改变
只是寻找 iFrame。

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.

稚然 2024-11-12 07:29:10

最近我也遇到了这个问题,我首先遵循 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 源已经更新以包含此更改

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文