Go Back  Xtreme Visual Basic Talk > Visual Basic .NET (2002/2003/2005/2008, including Express editions) > .NET General > Internet Explorer -- Get Elements/Submit Form


Reply
 
Thread Tools Display Modes
  #1  
Old 03-08-2007, 05:17 PM
jwakeman's Avatar
jwakeman jwakeman is offline
Contributor
 
Join Date: Jul 2005
Posts: 420
Default Internet Explorer -- Get Elements/Submit Form


I am able to get the html elements of a web browser control's document that is in my application using the following code:

Code:
Dim Hdoc As HtmlDocument = Me.WebBrowser1.Document Dim ElementCollection As HtmlElementCollection = doc.GetElementsByTagName("input") For Each Helement As HtmlElement In ElementCollection If Not Helement.GetAttribute("type") = "hidden" Then Me.ListBox1.Items.Add(Helement.Name) End If Next

I would like to be able to perform the same operation on a webpage in internet explorer, outside of my application. Can someone point me in the right direction?
Reply With Quote
  #2  
Old 03-14-2007, 12:44 PM
whlabus whlabus is offline
Freshman
 
Join Date: Mar 2007
Posts: 29
Default

This will create a new separate IE window and retrieve the data from it.

dim IEBrowser = CreateObject("InternetExplorer.Application")
IEBrowser.Visible = True
IEBrowser.Navigate("URL AS STRING (EX: http://www.google.com)")

Dim Hdoc As HtmlDocument = IEBrowser.Document
Dim ElementCollection As HtmlElementCollection = doc.GetElementsByTagName("input")
For Each Helement As HtmlElement In ElementCollection
If Not Helement.GetAttribute("type") = "hidden" Then
Me.ListBox1.Items.Add(Helement.Name)
End If
Next

I am actually doing something very similar currently, and am using this same code! Only I am looking for specific Username/Password fields on the webpage. (I'm making an auto-login program)

Anyway, this will gather all of the data from the webpage that is opened ONLY in the browser window created when you run the application. In other words, it won't work for any IE window that is open, say one that you open yourself. I am currently looking for a solution to this problem myself, and will update you here when I find one.

P.S. I'm writing this from my computer class at school, so it's off the top of my head. If the code doesn't work, or you have any problems/questions, just give a holler, I'll be home in about an hour, and I'll get the exact code needed from my program.

Hope this helps.
Reply With Quote
  #3  
Old 03-15-2007, 12:24 PM
jwakeman's Avatar
jwakeman jwakeman is offline
Contributor
 
Join Date: Jul 2005
Posts: 420
Default

Hey, what do ya know. I am also working on an auto-login app. Here is some code to loop through all the open internet explorer windows regardless of how they were created.

Code:
For Each ie As InternetExplorer In New ShellWindows Next

Note: You need to have a reference to Microsoft Internet Controls (SHDocVw.dll).
Reply With Quote
  #4  
Old 03-15-2007, 02:26 PM
whlabus whlabus is offline
Freshman
 
Join Date: Mar 2007
Posts: 29
Default

Thanks, you don't know how long I've been trying to figure out how to do that!

But, now I want to detect and control only the open IE window that is currently viewing a specified URL page. I tried this code:

For Each ie As InternetExplorer In New ShellWindows
If ie.Path = "http://www.google.com" Then
ie.Navigate("http://www.yahoo.com")
End If
Next

But it doesn't work, nothing happens to my IE window that is showing Google. Also, how do I assign ie to a new object?

Basically, I need my program to check periodically to see if the user is browsing a web page that he has saved login info for in my program, and then have my program take control of that window and fill out the fields.

Thanks for all of your help.
Reply With Quote
  #5  
Old 03-15-2007, 03:01 PM
jwakeman's Avatar
jwakeman jwakeman is offline
Contributor
 
Join Date: Jul 2005
Posts: 420
Default

Two things, use LocationURL and the forward slash at the end of "http://www.google.com/". path gives you the file system path to the executable. I'm not sure what you mean by assigning ie to a new object...it is already an object.

Code:
For Each ie As InternetExplorer In New ShellWindows If ie.LocationURL = "http://www.google.com/" Then ie.Navigate("http://www.yahoo.com") MessageBox.Show(ie.Path.ToString) End If Next
Reply With Quote
  #6  
Old 03-15-2007, 03:45 PM
whlabus whlabus is offline
Freshman
 
Join Date: Mar 2007
Posts: 29
Default

Thank you so much, you are my freakin hero.

One more thing though. Do you know how I can only control the window that has focus, because I noticed that when I run the code, it navigates to the site I want even if that window is minimized.

Thanks again for all of your help.
Reply With Quote
  #7  
Old 03-15-2007, 04:45 PM
jwakeman's Avatar
jwakeman jwakeman is offline
Contributor
 
Join Date: Jul 2005
Posts: 420
Default

You will need to use the windows api to see if the window is the foreground window:
Code:
Declare Function GetForegroundWindow Lib "user32" Alias "GetForegroundWindow" () As Integer sub() For Each ie As InternetExplorer In New ShellWindows If GetForegroundWindow = ie.HWND Then MessageBox.Show(ie.LocationURL.ToString) End If Next end sub


Also, I have learned that you can listen to the ie window's events as well as the document's events. Very exciting!

Code:
sub() For Each ie As InternetExplorer In New ShellWindows If GetForegroundWindow = ie.HWND Then AddHandler ie.DocumentComplete, AddressOf handledocumentcomplete Dim hdoc As HTMLDocument = ie.Document AddHandler hdoc.onmousedown, AddressOf handlemousedown End If Next end sub Sub handledocumentcomplete(ByVal pDisp As Object, ByRef url As Object) MessageBox.Show("Caught complete") End Sub Sub handlemousedown() MessageBox.Show("Caught click") End Sub
Reply With Quote
  #8  
Old 03-15-2007, 06:08 PM
whlabus whlabus is offline
Freshman
 
Join Date: Mar 2007
Posts: 29
Default

I tried implementing your code:

If GetForegroundWindow = ie.HWND Then

but when I run my progrma nothing happens. I also tried the Sub you posted that shows a message box but that didn't work either.
Reply With Quote
  #9  
Old 03-15-2007, 07:50 PM
jwakeman's Avatar
jwakeman jwakeman is offline
Contributor
 
Join Date: Jul 2005
Posts: 420
Default

What did you do wrong? Do you know how to debug: i.e. set break points, add watches, etc?
Reply With Quote
  #10  
Old 03-16-2007, 07:00 AM
jwakeman's Avatar
jwakeman jwakeman is offline
Contributor
 
Join Date: Jul 2005
Posts: 420
Default

Quote:
Originally Posted by jwakeman View Post
What did you do wrong? Do you know how to debug: i.e. set break points, add watches, etc?
I was getting a little tired last night....let me know if you still can't get the code to work!
Reply With Quote
  #11  
Old 03-16-2007, 03:38 PM
whlabus whlabus is offline
Freshman
 
Join Date: Mar 2007
Posts: 29
Default

Alright, I figured out that I don't need the app to only automate the open window. Also, when I tried your other code for detecting when a page has loaded:

Sub detectieload()
For Each ie As InternetExplorer In New ShellWindows
If GetForegroundWindow = ie.HWND Then
AddHandler ie.DocumentComplete, AddressOf handledocumentcomplete
Dim hdoc As HTMLDocument = ie.Document
End If
Next
End Sub
Sub handledocumentcomplete(ByVal pDisp As Object, ByRef url As Object)
MessageBox.Show("Caught complete")
End Sub

When it detects that a page has loaded, it gives the error on the line:

Dim hdoc As HTMLDocument = ie.Document

Unable to cast COM object of type 'mshtml.HTMLDocumentClass' to class type 'System.Windows.Forms.HtmlDocument'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

I was wondering what might be wrong.
Reply With Quote
  #12  
Old 03-17-2007, 03:33 PM
jwakeman's Avatar
jwakeman jwakeman is offline
Contributor
 
Join Date: Jul 2005
Posts: 420
Default

You need to add a reference to the 'Mircrosoft HTML Object Library', found under the COM tab when you add a reference to your project. Then use the following imports statement:

Code:
Imports mshtml
Reply With Quote
  #13  
Old 03-19-2007, 07:58 PM
whlabus whlabus is offline
Freshman
 
Join Date: Mar 2007
Posts: 29
Default

OK, that got rid of that error, but now I've set a timer up on my form that executes Sub detectieload() on every Timer1_Tick event, but when I run the program, as soon as I even give focus to my IE window, an error on the line occurs:

AddHandler ie.DocumentComplete, AddressOf handledocumentcomplete

COM object that has been separated from its underlying RCW cannot be used.
Reply With Quote
  #14  
Old 03-21-2007, 06:50 AM
jwakeman's Avatar
jwakeman jwakeman is offline
Contributor
 
Join Date: Jul 2005
Posts: 420
Default

First of all you only want to use the addhandler line once for a browser window. It looks like you are executing that line each time the timer ticks. Anyway I see two approaches to doing autologin on a web page and I am not sure which you are going for.

1. Have a timer and in the tick event cycle through all the open internet browser windows looking for one that meets your criteria. Basically you are trying to detect when the user has navigated to a URL that you have the login info for. I should say I don't like this design but it might look like this.

Code:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick For Each ie As InternetExplorer In New ShellWindows If ie.LocationURL = "http://mail.google.com" Then Do Until ie.ReadyState = tagREADYSTATE.READYSTATE_COMPLETE Application.DoEvents() Loop 'get the HTML elements, fill there values, etc as we have covered already End If Next End Sub


2. Through a form (or I was thinking a notify icon in the tray) let the user select a webpage from a list of stored "autologins". When the user selects the page you launch IE, navigate to the page, wait for it to load and log in. I have been using system.diagnostics.process and the GetWindowThreadProcessId API to find the IE I spawned and then hook into the documentcomplete event for that IE.

Code:
Declare Function GetWindowThreadProcessId Lib "user32" Alias "GetWindowThreadProcessId" (ByVal hwnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer Private Sub LoadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LoadButton.Click Dim p as system.diagnostics.process = Process.Start("iexplore", "http://mail.google.com") p.WaitForInputIdle(30000) ' Not sure Do Until p.Responding = True ' which of these or Application.DoEvents() ' which combination of these Loop ' does the trick but you need System.Threading.Thread.Sleep(50) ' to wait for the process to get started so you don't miss the IE you spawned when you loop through them For Each ie In New ShellWindows Dim threadID As Integer = 0 Dim tmpPID As Integer = 0 threadID = GetWindowThreadProcessId(ie.HWND, tmpPID) If p.Id = tmpPID Then AddHandler ie.DocumentComplete, AddressOf HandleDocumentComplete Exit For End If Next End Sub Sub HandleDocumentComplete(ByVal pdisp As Object, ByRef url As Object) 'Do the login End Sub

Of course maybe all I needed to tell you is that you could use

Code:
if ie.ReadyState = tagREADYSTATE.READYSTATE_COMPLETE then ' Do the login end if

in your timer in order to detectieloady.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->