Hi,
After spending the whole day on it I have found a solution.
This is a known issue that Microsoft have chosen not to fix...
[
lab.msdn.microsoft.com]
The problem is that we have to read the InternetExplorer.Document at the right time and from the right thread. We have to wait until the main frameset is loaded, but we have to read before the first frame is completed...
In the example below I know that there are three frames and I want to be sure that they are all loaded before I access them (This is another problem you have to avoid...)
/Patrick
using System;
namespace ConsoleApplication7
{
/// <summary>
/// Summary description for Class1.
/// </summary>
using System;
using mshtml;
using SHDocVw;
using System.Collections;
using System.Threading;
namespace ConsoleApplication1
{
class Class1
{
static InternetExplorer ie = null;
[STAThread]
static void Main(string[] args)
{
Class1 class1 = new Class1();
class1.Test();
Console.Read();
}
AutoResetEvent firstDocumentCompleted;
AutoResetEvent lastDocumentCompleted;
int completedDocuments;
int expectedDocuments;
public void Test()
{
Console.WriteLine("Starting:" + Thread.CurrentThread.ApartmentState.ToString());
ie = new SHDocVw.InternetExplorer();
ie.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(DocumentComplete);
ie.Visible = true;
firstDocumentCompleted = new AutoResetEvent(false);
lastDocumentCompleted = new AutoResetEvent(false);
completedDocuments = 0;
expectedDocuments = 4;
object o = null;
ie.Navigate("http://www.htmq.com/html/sample/frame.htm", ref o, ref o, ref o, ref o);
firstDocumentCompleted.WaitOne(30000, false);
IHTMLDocument2 document = (IHTMLDocument2)ie.Document;
lastDocumentCompleted.WaitOne(30000, false);
IHTMLFramesCollection2 frames = (IHTMLFramesCollection2)document.frames;
for (int index = 0; index < frames.length; index++)
{
object i = index;
frames.item(ref i);
IHTMLWindow2 window = (IHTMLWindow2)frames.item(ref i);
IHTMLDocument2 frameDocument = (IHTMLDocument2)window.document;
Console.WriteLine(frameDocument.body.innerHTML);
}
Console.WriteLine();
}
public void DocumentComplete(object pDisp, ref object URL)
{
Console.WriteLine("DocumentComplete:" + Thread.CurrentThread.ApartmentState.ToString());
if (completedDocuments == 0)
{
firstDocumentCompleted.Set();
}
Interlocked.Increment(ref completedDocuments);
if (completedDocuments == expectedDocuments)
{
lastDocumentCompleted.Set();
}
}
}
}
}