Quantcast
Channel: Internet Explorer Web Development forum
Viewing all articles
Browse latest Browse all 3527

How to get HTML of a frame

$
0
0

Hi,

I posted this question on ASP.net forums but was deleted because it was considered off-topic. Now I repost it here hoping that someone shed some light on the issue. The query has to do with programmatic access to the DOM, HTML documents, frames and javascript.
Here is my original post:

I'm trying to automate the reboot process of a TP-link router in C# by programmatically simulating the manual navigation through its web interface, from logon up to the reboot option. The router's web interface is initially loaded on a WPF's "WebBrowser" control, referenced as "wbTplink" in codebehind. The fact that I used a WPF control is not relevant to this post. What's important are the types and methods from the "Microsoft.mshtml" namespace that I'm trying to use for the task, but with little success so far.

The web interface implements:

  • Forms authentication
  • Several frames
  • Lots of javascrip

Fig. #1 shows the logon window.
Fig. #2 shows the landing page after logon.

Long story short, I could successfully log on and navigate through the javascript menu items until I reach the "Reboot" tab.  The "Reboot" tab, together with other three tabs, resides on its own frame on the right-hand side of the window. The closest I could get to rebooting the router is shown in Fig. #3. From there, the idea is to programmatically click the "Reboot" button (id=btn_reboot), or, even better, run the "doReboot()" javascript function. The problem is that I'm unable to retrieve the IHTEMLDocument of the tab where the "btn_reboot" button and the doReboot() javascript function are defined. No matter what index number I use for the frame, I either get the document that corresponds to the content rendered on Fig. #2 (ref_index=1) or just nothing due to exceptions on unmanaged code from "mshtml". Of course, the IHTMLDocument that I get from setting ref_index=1 doesn't contain the "btn_reboot" button or the "doReboot()" function simply because it doesn't correspond to the content that's being rendered by the wbTplink control (Fig. #3). Simply put, I just can't find a way to reach the HTML code of the "Reboot" tab. To make things worse, navigating to the "Reboot" tab doesn't raise wbTplink's "LoadCompleted" event.

So, with Fig. #3 in mind, my question simply is this: What do I have to do to programmatically get the HTML document of the "Reboot" tab that's on the frame to the right-hand side of the wbTplink window?

See the XAML and C# code and comments for more context. Only the relevant pieces are pasted:

<WebBrowser Name="wbTplink" Source="http://192.168.1.2/" Width="600" Height="600" LoadCompleted="wbTplink_LoadCompleted"/>

private void wbTplink_LoadCompleted(object sender, NavigationEventArgs e) { HTMLDocumentClass docClass = wbTplink.Document as HTMLDocumentClass; IHTMLElement usr = docClass.getElementById("txt_usr_name"); usr.innerText = "Administrator"; IHTMLElement pas = docClass.getElementById("txt_password"); pas.innerText = "MyPassword"; IHTMLElement btn = docClass.getElementById("btn_logon"); wbTplink.LoadCompleted -= wbTplink_LoadCompleted; // Raised after logon window is rendered. wbTplink.LoadCompleted += wbTplink_LoadCompleted1; // Raised after "btn.click()" btn.click(); } private void wbTplink_LoadCompleted1(object sender, NavigationEventArgs e) { // Flow continues here ... wbTplink.LoadCompleted -= wbTplink_LoadCompleted1; // This event is never raised. // Not even after the navigate() method finishes rendering the "Reboot.htm" file. See [*] below. wbTplink.LoadCompleted += wbTplink_LoadCompleted2; // BEGIN Fig. #3 // ------------- object ref_index = 0 as object; HTMLDocumentClass docClass = wbTplink.Document as HTMLDocumentClass; IHTMLFramesCollection2 frames = docClass.frames; IHTMLWindow2 currentFrame = (IHTMLWindow2)frames.item(ref ref_index); HTMLDocument document_sub = ((HTMLDocument)currentFrame.document); // This gets the HTML of all the items that comprise the javascript menu on // the frame to the left of the window. IHTMLElement element_sub = (document_sub.getElementById("div_menu")); // GREAT! This works. IHTMLElement maintenance = (document_sub.getElementById("a28")); maintenance.click(); // So far, so good. ref_index = 1 as object; IHTMLWindow2 currentFrame1 = (IHTMLWindow2)frames.item(ref ref_index); // [*] currentFrame1.navigate("http://192.168.1.2/userRpm/Reboot.htm"); // END Fig. #3 // ----------- // No matter what I do below, it is impossible to retrieve the HTML // document of the "Reboot.htm" page. // The following code retrieves the HTML that corresponds to the frame shown in Fig. #2 // even though Fig. #3 is rendered on the wbTplink control. // I want the HTML shown in Fig. #3 so that I have access to btn_reboot or doReboot(). // Trying different values of ref_index doesn't make any difference. HTMLDocument document_sub2 = ((HTMLDocument)currentFrame1.document); IHTMLElement element_sub2 = (document_sub2.getElementById("div_main_pane")); MessageBox.Show(element_sub2.innerHTML); // This works only if "ref_index = 1" } private void wbTplink_LoadCompleted2(object sender, NavigationEventArgs e) { // This event handler is never called because navigating through the // javascript menu items, which refreshes the right-hand frame, doesn't raise // the LoadCompleted event. } }

Thank you in advance.
Fernando Ronci


Viewing all articles
Browse latest Browse all 3527

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>