Accessing Frames throws InvalidCastException

Add-in Express™ Support Service
That's what is more important than anything else

Accessing Frames throws InvalidCastException
 
Steve Syfuhs




Posts: 8
Joined: 2014-07-29
I'm trying to get a pages' frameset. This is a reproducible error too as I've been able to create a sample to test it against.

I'm getting the following exception:


System.InvalidCastException: Specified cast is not valid.
   at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
   at mshtml.HTMLDocumentClass.get_frames()
   at My.NameSpace.GetTargetWindow(String getFrameBy, String frameVal, HTMLDocument htmlDocument)


This is occurring when it's trying to access the Document.frames property. E.g.


targetWin = htmlDocument.frames.item(frameVal);


It looks to be blowing up in the frames property getter, not the actual item(...) method.

This is being run on a x86 IE 10 instance, on a x64 Windows 8 machine. The ADX library is the latest released version.

Any ideas?
Posted 29 Jul, 2014 16:17:46 Top
Sergey Grischenko


Add-in Express team


Posts: 7233
Joined: 2004-07-05
Hi Steve,

Do you read the 'frames' property in the DocumentComplete event handler?
Posted 30 Jul, 2014 12:55:58 Top
Steve Syfuhs




Posts: 8
Joined: 2014-07-29
The frames are accessed from a stack originating from IEModule_DocumentComplete2. Should this be hooked in the original DocumentComplete instead?
Posted 05 Aug, 2014 11:15:32 Top
Andrei Smolin


Add-in Express team


Posts: 18827
Joined: 2006-05-11
Hello Steve,

This should start from DocumentComplete2.

Does the same occur if you invoke this code only when the rootDocLoaded parameter is true?


Andrei Smolin
Add-in Express Team Leader
Posted 06 Aug, 2014 05:38:00 Top
Steve Syfuhs




Posts: 8
Joined: 2014-07-29
Andrei,
That is correct. We only execute when rootDocLoaded == true and when HTMLDocument != null. This is the gist of how our code works:


private void IEModule_DocumentComplete2(object pDisp, string url, bool rootDocLoaded)
{
	if (!rootDocLoaded || this.HTMLDocument == null) 
	{
		return;
	}
	
	var frame = GetTargetWindow("name", "somename", this.HTMLDocument);
	
	if (frame != null)
	{
		// go do frame stuff
	}

	// snip...
}

private void GetTargetWindow(string getFrameBy, string frameVal, HTMLDocument htmlDocument)
{
	// under a given condition this will get called
	// and the exception is thrown
	var targetWin = htmlDocument.frames.item(frameVal);
	
	// alternatively this line will also throw
	var framesCollection = htmlDocument.frames; // this tells me its something internally in the frames getter
	
	return targetWin;
}
Posted 06 Aug, 2014 11:19:28 Top
Andrei Smolin


Add-in Express team


Posts: 18827
Joined: 2006-05-11
Steve,

This works for me if I pass an integer to htmlDocument.frames.item(intIndex), not a string. If I pass a string, I get this exception:

Exception Type: System.Runtime.InteropServices.COMException
Exception Message: Type mismatch.

Exception Target Site: ForwardCallToInvokeMember

---- Stack Trace ----
System.RuntimeType.ForwardCallToInvokeMember(memberName As String, flags As BindingFlags, target As Object, aWrapperTypes As Int32[], msgData As MessageData&)
mscorlib.dll: N 0197 (0xC5) IL
mshtml.HTMLWindow2Class.item(pvarIndex As Object&)
mscorlib.dll: N 00000 (0x0) JIT
MyIEAddon19.IEModule.GetTargetWindow(getFrameBy As String, frameVal As String, htmlDocument As HTMLDocument)
IEModule.cs: line 0157, col 13, IL 0073 (0x49)
MyIEAddon19.IEModule.IEModule_DocumentComplete2(pDisp As Object, url As String, rootDocLoaded As Boolean)
IEModule.cs: line 0135, col 13, IL 0043 (0x2B)
AddinExpress.IE.ADXIEModule.ADXIEModule_DocumentComplete(pDisp As Object, url As Object&)
mscorlib.dll: N 0000 (0x0) IL


Andrei Smolin
Add-in Express Team Leader
Posted 07 Aug, 2014 04:37:09 Top
Steve Syfuhs




Posts: 8
Joined: 2014-07-29
Andrei,
I've tried passing both an int and a string and they both throw the same exception. As I said, I don't think this is occurring in the method, but in the property getter.

This is the page that I'm trying to work against:


<html>
<head>
<title>Is a test</title>
</head>
<frameset rows="*,1">
	<frame src="thing1.html" name="frame1" noresize scrolling="no">
	<frame src="thing2.html" name="frame2" noresize scrolling="no">
</frameset>
</html>


As I understand it, this would be the root document, and once it's loaded I should be able to get the frameset?

As well, I tried using a querySelector:


var frame = htmlDocument.querySelector('frameset');


This will throw the same exception when I try and touch any properties on the frame.

I've even tried using the helper:


var frames = ADXIEHelper.GetFrames(htmlDocument);


The returned collection is empty, however I can see there's a first chance exception matching the original exception above, which occurs because it looks like the helper is catching and returning an empty array.
Posted 07 Aug, 2014 10:36:37 Top
Andrei Smolin


Add-in Express team


Posts: 18827
Joined: 2006-05-11
Could you also copy the exception details here? Is there a call stack?


Andrei Smolin
Add-in Express Team Leader
Posted 07 Aug, 2014 10:41:09 Top
Steve Syfuhs




Posts: 8
Joined: 2014-07-29
I'm not sure if this applies, but this is occurring over an HTTPS connection too. Could the security model be getting in the way?
Posted 07 Aug, 2014 10:43:08 Top
Andrei Smolin


Add-in Express team


Posts: 18827
Joined: 2006-05-11
I don't think so.


Andrei Smolin
Add-in Express Team Leader
Posted 07 Aug, 2014 10:50:01 Top