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

C# 在新版本2.1中访问Watin中的帧时出错,c#,watin,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

访问新版本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()

请帮我解决这个问题。

您可以通过访问
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;
   }
Element-ElementFromFrames(字符串elementId,IList-frames)
{ 
foreach(帧中的变量f)
{
var e=f.Body.allsubstands.GetElementsById(elementId).FirstOrDefault();
如果(e!=null)返回新元素(即,e);
如果(f.Frames.Count>0)
{var ret=ElementFromFrames(elementId,f.Frames);
如果(ret!=null)返回ret;
}
}     
返回null;
}
来自

此问题似乎是由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;
}
public AllFramesProcessor(HTMLDocument htmlDocument)
{
Elements = new List<INativeDocument>();
_htmlDocument = htmlDocument;

_iFrameElements =
(IHTMLElementCollection)htmlDocument.all.tags("iframe");
}
2.1中的构造函数如下所示:

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;
}
public AllFramesProcessor(HTMLDocument htmlDocument)
{
Elements = new List<INativeDocument>();
_htmlDocument = htmlDocument;

_iFrameElements =
(IHTMLElementCollection)htmlDocument.all.tags("iframe");
}
public所有框架处理器(HTMLDocument HTMLDocument)
{
元素=新列表();
_htmlDocument=htmlDocument;
_iFrameElements=
(IHTMLElementCollection)htmlDocument.all.tags(“iframe”);
}
通过将
“htmlDocument.all.tags(“iframe”)”
更改为
“htmlDocument.all.tags(“frame”)”
符合Watin 1.3本构造函数的要求 似乎解决了这个问题。不太清楚为什么要更改构造函数
只是为了寻找iFrame。

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

在此之前,我对Watin中继进行了SVN更新。Jeroen于2011年4月18日签入,修复了WaitForFrameToComplete重试/等待加载主文档的问题。单是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");
    }
}
public所有框架处理器(HTMLDocument HTMLDocument)
{
元素=新列表();
_htmlDocument=htmlDocument;
//错误修复,尝试恢复到以前的版本
// 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(“框架”);
//如果当前文档不包含框架元素,则
//可能包含IFRAME元素。
if(_iframelements.length==0)
{
_iframelements=(IHTMLElementCollection)_htmlDocument.all.tags(“iframe”);
}
}

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

您正在使用哪个版本的IE和windows?我在win7/IE9和XP/IE7mark上对此进行了测试,你能详细说明一下如何使用你的解决方案吗?我不想更改源代码并编译我自己的WatiN版本,但我似乎需要更多的上下文来支持你提出的解决方案。虽然已经有一段时间了,但我的示例似乎没有明确包括
ie
变量,我猜它存储在同一个类的一个字段中。。。?看起来,
ie.NativeDocument.Frames
是为
Frames
参数传入的。