I want to open separate instances of internet explorer to specified websites. After they are open I would like to cycle through them being displayed on a timer.
I have the following code, but I am not able to switch to the specified IE process:
Dim rotatethrough As Boolean = True
For i = 0 To ListBox1.Items.Count - 1 'I have a list box that contains the website URLs
Dim Processname As New List(Of String)
Dim processnum(Environment.ProcessorCount) As Process
processnum(i) = New Process
processnum(i) = System.Diagnostics.Process.Start(ListBox1.Items(i)) 'start up seperate instances of IE for each website
Next
Do While rotatethrough = True
For n = 0 To ListBox1.Items.Count - 1
AppActivate(processnum(n).Id) 'activate the websites
Threading.Thread.Sleep(1000)
Next
Loop
So far the code opens up the separate instance of IE but fails on appactivate because " Object reference not set to an instance of an object.". I have tried creating IE as an object, but then I am not sure how to get the correct process ID for the corresponding listbox item.
ANY help would be awesome, I just can seem to figure this one out.
Related
Here is my requirement which I intend to implement. There is one window application showing some icons which take me to different web sites. When I click on one of the icons, it should open an IE window and append a customized name to it.
So, before opening any website after I click on website icon, I want to check if there is already an IE window open with that customized name, if yes, bring that already opened window to the foreground. If not, open a new IE window.
I have checked various questions posted which are related to what I am looking to achieve, but am somehow not able to get it right. Below is my attempt.
For Each e In shellWins
If InStr(1, e.GetProperty("IEWindowName"), namedWindow, CompareMethod.Text) <> 0 Then
hWnd = e.HWND
myIE = e
End If
Next
If hWnd == -1
Dim p As New Process
Dim psi As New ProcessStartInfo(IEPath, webSiteURL)
p.StartInfo = psi 'Trying to open a new IE window
p.Start()
For Each ie In shellWins
If ie.hwdn = p.MainWindowHandle Then
ie.PutProperty("IEWindowName", namedWindow)
End If
Next
End if
Else
myIE.BringToForeground()
This sometime works and sometimes does not. Is there any better way to do it?
It doesn't work in which situation? Does there any error throw when it doesn't work? If there is, please tell us the detailed error information and in which line it occurs.
Besides, you could try to compare the url to check if the website is already open in IE like this:
Sub Main()
Dim shellWins As SHDocVw.ShellWindows
Dim explorer As SHDocVw.InternetExplorer
shellWins = New SHDocVw.ShellWindows
Dim SQuery As String = "https://www.example.com/"
For Each explorer In shellWins
If explorer.Application.Name = "Internet Explorer" And explorer.LocationURL.Contains(SQuery) Then
explorer.BringToForeground()
End If
Next
shellWins = Nothing
explorer = Nothing
End Sub
I have created a simple FORM in VB.NET that takes some details and then needs to log in to 3 locations using this information.
At the moment I have the code so it takes this data from the textBoxs and assigns them to 4 different variables. From there I have also opened up the three different websites.
I am having difficulties finding how I will take the variables and then populate the corresponding field on the web application. Any suggestions?
My Code:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Define Store variable
Dim Store As String
Store = Me.TextBox1.Text
'Define IP Address variable
Dim IPAddress As String
IPAddress = Me.TextBox2.Text
'Define Username variable
Dim Username As String
Username = Me.TextBox3.Text
'Define Password variable
Dim Password As String
Password = Me.TextBox4.Text
' Open Store Specific URL 1
Dim WebAddress1 As String = "http://" & IPAddress & ":"
Process.Start(WebAddress1)
getElementByName
' Open Store Specific URL 2
Dim WebAddress2 As String = "http://somedomain2.com"
Process.Start(WebAddress2)
' Open Store Specific URL 3
Dim WebAddress3 As String = "http://somedomain3.com"
Process.Start(WebAddress3)
End Sub
End Class
What you need to do is identify the element name that you want to populate. This can typically done by going to the web page, and pressing View Source (changes by web browser, some you can right click and it will be there, some you can access through the settings button.)
Once looking at the source, you will want to find the object (usually a text box or something along those lines) where you want to send the information. Usually these boxes have titles, like Username, or Password. So I would recommend doing a Ctrl + F search based on the information you can see on the site. I see in your code you have GetElementByName, and that's exactly what you'll do. You will want to store
Here's an example code:
Dim IE As Object 'Internet explorer object
Dim objCollection As Object 'Variable used for cycling through different elements
'Create IE Object
IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate("https://somewebsite.com/") 'Your website
Do While IE.Busy
Application.DoEvents() 'This allows the site to load first
Loop
'Find the field you are looking for and store it into the objCollection variable
objCollection = IE.document.getelementsbyname("CustomerInfo.AccountNumber") 'The "CustomerInfo.AccountNumber" is the name of the element I looked for in this case.
'Call element, and set value equal to the data you have from your form
objCollection(0).Value = MainForm.tbLoan.Text
' Clean up
IE = Nothing
objCollection = Nothing
This should be a good start for you. There are multiple resources on this site that might be able to give you additional information when it comes to entering data into websites using vb.net.
Hopefully this helps!
I am very new to VB.NET and currently learning how to scrape and parse websites. My problem in a nutshell is - if I use “getElementsByClassName” more than one time in my code, it will only work the first time. Same situation with “getElementsByTagName”. And even when I just parse html code manually it will only work the first time.
Here is an example using “getElementsByClassName”. I have Form1 with Button 1 and ListBox1. I am trying to get news titles from two websites (Google and BBC) and then put them into the ListBox1. You can see I split my code into two parts. I would like to point out that both parts work very well and get the information I need, but only when used individually. When put together like in the example below, the first part (Google) will execute without problems but the second part (BBC) will give me an error on line “Dim AllItemsBBC As Object = SecondBrowser.Document.getElementsByClassName("title-link__title-text")”.
Now what’s more interesting, if I flip the code around and put the BBC part first and Google second, BBC will execute without problems and Google will give me error on line “Dim AllItemsGoogle As Object = FirstBrowser.Document.getElementsByClassName("titletext")”. Basically whichever is first executes without problems, second one fails.
The error message shows “An unhandled exception of type 'System.NotSupportedException' occurred in Microsoft.VisualBasic.dll Additional information: Exception from HRESULT: 0x800A01B6”.
Example1:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'START OF PART 1
'Creating and navigating the IE browser to Google news page
Dim FirstBrowser As Object = CreateObject("InternetExplorer.Application")
FirstBrowser.Visible = True
FirstBrowser.Navigate("https://news.google.com/news?cf=all&pz=1&ned=us")
Do
Application.DoEvents()
Loop Until FirstBrowser.readyState = 4
'Getting the titles from Google news page and adding them to ListBox1
Dim ItemGoogle As Object
Dim AllItemsGoogle As Object = FirstBrowser.Document.getElementsByClassName("titletext")
For Each ItemGoogle In AllItemsGoogle
ListBox1.Items.Add(ItemGoogle.InnerText)
Next ItemGoogle
'Closing the browser
FirstBrowser.Quit()
'END OF PART1
'START OF PART 2
'Creating and navigating the IE browser to BBC news page
Dim SecondBrowser As Object = CreateObject("InternetExplorer.Application")
SecondBrowser.Visible = True
SecondBrowser.Navigate("http://www.bbc.com/news")
Do
Application.DoEvents()
Loop Until SecondBrowser.readyState = 4
'Getting the titles from BBC news page and adding them to ListBox1
Dim ItemBBC As Object
Dim AllItemsBBC As Object = SecondBrowser.Document.getElementsByClassName("title-link__title-text")
For Each ItemBBC In AllItemsBBC
ListBox1.Items.Add(ItemBBC.InnerText)
Next ItemBBC
'Closing the browser
SecondBrowser.Quit()
'END OF PART 2
End Sub
End Class
My second example is me parsing same websites by basically just finding the phrases I need. Same situation, Google part works, BBC fails on line “Dim the_html_code_bbc As String = SecondBrowser.Document.Body.InnerHTML”.
Flip it around and BBC works and Google fails on line “Dim the_html_code_google As String = FirstBrowser.Document.Body.InnerHTML”.
The error message shows “An unhandled exception of type 'System.MissingMemberException' occurred in Microsoft.VisualBasic.dll Additional information: Public member 'InnerHTML' on type 'JScriptTypeInfo' not found.”
Example 2
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'START OF PART 1
'Creating and navigating the IE browser to Google news page
Dim FirstBrowser As Object = CreateObject("InternetExplorer.Application")
FirstBrowser.Visible = True
FirstBrowser.Navigate("https://news.google.com/news?cf=all&pz=1&ned=us")
Do
Application.DoEvents()
Loop Until FirstBrowser.readyState = 4
'Getting the titles from Google news page and adding them to ListBox1
Dim the_html_code_google As String = FirstBrowser.Document.Body.InnerHTML
Dim start_of_code_google As String
Dim code_selection_google As String
Do
Application.DoEvents()
start_of_code_google = InStr(the_html_code_google, "titletext")
If start_of_code_google > 0 Then
code_selection_google = Mid(the_html_code_google, start_of_code_google + 11, Len(the_html_code_google))
the_html_code_google = Mid(the_html_code_google, start_of_code_google + 11, Len(the_html_code_google))
code_selection_google = Mid(code_selection_google, 1, InStr(code_selection_google, Chr(60)) - 1)
ListBox1.Items.Add(code_selection_google)
End If
Loop Until start_of_code_google = 0
'Closing the browser
FirstBrowser.Quit()
'END OF PART1
'START OF PART 2
'Creating and navigating the IE browser to BBC news page
Dim SecondBrowser As Object = CreateObject("InternetExplorer.Application")
SecondBrowser.Visible = True
SecondBrowser.Navigate("http://www.bbc.com/news")
Do
Application.DoEvents()
Loop Until SecondBrowser.readyState = 4
'Getting the titles from BBC news page and adding them to ListBox1
Dim the_html_code_bbc As String = SecondBrowser.Document.Body.InnerHTML
Dim start_of_code_bbc As String
Dim code_selection_bbc As String
Do
Application.DoEvents()
start_of_code_bbc = InStr(the_html_code_bbc, "title-link__title-text")
If start_of_code_bbc > 0 Then
code_selection_bbc = Mid(the_html_code_bbc, start_of_code_bbc + 24, Len(the_html_code_bbc))
the_html_code_bbc = Mid(the_html_code_bbc, start_of_code_bbc + 24, Len(the_html_code_bbc))
code_selection_bbc = Mid(code_selection_bbc, 1, InStr(code_selection_bbc, Chr(60)) - 1)
ListBox1.Items.Add(code_selection_bbc)
End If
Loop Until start_of_code_bbc = 0
'Closing the browser
SecondBrowser.Quit()
'END OF PART 2
End Sub
End Class
Another thing worth mentioning is that if I use one method of parsing for the Google part and a different method for BBC, everything works great.
I must be missing something due to my inexperience with Visual Studio. I am using Express 2013 for Windows Desktop version. If you know what’s causing this issue, I would greatly appreciate your advice.
My goal is to create a VB application that reads and writes information to various webpages loaded in Internet explorer.
I have created a program that works exactly as I intend in VBA. I am now trying to re-implement the same programming in VB.
I have a function that looks for and returns an Internet Explorer Object where the input matches the LocationName.
Assuming the target page is loaded, I can work with it. Methods such as getElementByID() work perfectly. If the browser window is closed and reopened, and the code is run again, the results are very inconsistent. The getIE function seems to work, but when trying to use methods like document.getElementByID() a NullReferenceException is thrown.
Does anyone know if there is anything I am missing that I need to include to get the document property to update?
EDIT: I have looked over the NullReferenceException article. It hasn't helped me unfortunately. In case I was unclear in my wording, I would like to reiterate that the same bit of code yields a different result when executed the 2nd time under the same conditions (same webpage open in Internet Explorer).
On the second execution IE.locationName is retrievable but IE.Document.title is not. The problem is definitely with the Document property as far as I can tell. I am truly stumped.
Many thanks
Public Function getIE(targetTitle As String) As SHDocVw.InternetExplorer
' Create the shell application and Collection of open windows
Dim shellObj As Object = CreateObject("Shell.Application")
Dim shellWindows As SHDocVw.ShellWindows = shellObj.Windows()
getIE = Nothing
' Scan through the Collection
For I = (shellObj.Windows.Count - 1) To 0 Step -1
' If found, assign this to the function output and exit early
If InStr(shellWindows(I).LocationName, targetTitle) Then
getIE = shellWindows(I)
Debug.Print("Found: " & shellWindows(I).LocationName)
Exit For
End If
Next I
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim IE As SHDocVw.InternetExplorer
IE = getIE("my site title")
If IE Is Nothing Then
Debug.Print("Site not open")
Exit Sub
End If
' The code always gets this far, and despite the page being found, starts throwing exceptions from here on if the window has been closed and reopened whilst my application has stayed running.
' Sample form data insertion code
IE.Document.getElementById("textbox1").value = "my value"
' Click the submit button
IE.Document.getElementById("submit").click()
' Wait for page to load
While IE.Busy
End While
IE.Document.getElementById("textbox2").value = "my 2nd value"
' done
IE = Nothing
End sub
I create a browser like so, and manually navigate to the web page I need to be. I intend to automatically pull certain elements once I get to the page I need to be on via a seperate macro
Sub Test()
Set CAS = New SHDocVw.InternetExplorer ' create a browser
CAS.Visible = True ' make it visible
CAS.navigate "http://intraneturl"
Do Until CAS.readyState = 4
DoEvents
Loop
This works fine, then I do
Public Sub Gather
Set HTMLDoc2 = CAS.document.frames("top").document
Call Timer1
With HTMLDoc2
.getElementById("tab4").FirstChild.Click
End With
Call Timer2
Dim fir, las, add1, add2, cit, stat, zi As String
Dim First As Variant
Dim Last As Variant
Dim addr1 As Variant
Dim addr2 As Variant
Dim city As Variant
Dim Thisstate As Variant
Dim Zip As Variant
Call Timer2
Set HTMLDoc = CAS.document.frames("MainFrame").document
Call Timer2
With HTMLDoc
First = .getElementsByName("IndFirst")
Last = .getElementsByName("IndLast")
addr1 = .getElementsByName("txtAdd_Line1")
addr2 = .getElementsByName("txtAdd_Line2")
city = .getElementsByName("txtAdd_City")
Thisstate = .getElementsByName("cmb_Add_State")
Zip = .getElementsByName("txtAdd_Zip")
End With
fir = First.Value
las = Last.Value
add1 = addr1.Value
add2 = addr2.Value
cit = city.Value
stat = Thisstate.Value
zi = Zip.Value
'navigate back to start page
With HTMLDoc2
.getElementById("tab3").FirstChild.Click
End With
End Sub
This works the first time, but after the first time, I get "Object variable or with block variable not set" when trying to run the gather() sub again, on a different web page that contains similar information. Any Ideas as to what im doing wrong?
"The error "object variable or with block variable not set" occurs on: Set HTMLDoc2 = CAS.document.frames("top").document the second time i try running Gather()."
This is probably one of three things:
CAS is no longer an object
To check this, set a breakpoint on the line, press ctr+G in the VBA Editor and type ?CAS Is Nothing in the Immediate Window; the result should be False; if it is True CAS is no longer an object
Like Daniel Dusek suggested, make sure CAS.document.frames("top") is an actual element on the page.
To check this, open the webpage you are trying to script, press F12 in Internet Explorer, click on the arrow in the toolbar and click on the "top" frame element in the webpage, switch back to the Developer Tool and look at the line highlighted. Make sure the frame element is named "top".
The HTML hasn't fully loaded when you try to reference the frame element. Set a longer delay or a loop.
i.e. (untested):
Do Until HtmlDoc2 Is Nothing = false
Set HTMLDoc2 = CAS.document.frames("top").document
Loop
Maybe the more important question is why manually navigate to another page? Can't you automate that part of your process too?