How to get HTML Document height using CEFSHARP? - vb.net

I'm changing a web browser application to use the CEFSHARP chromium based browser instead of the inbuilt vb.net web browser control and need to query the html document to be able to set the browser control height to the height of the html page. In the VB web browser control I've used the following to set the height.
WebBrowser.Height = WebBrowser.Document.Body.ScrollRectangle.Height
WebBrowser.Height = WebBrowser.RectangleToScreen
How can you get the HTML document properties in CEFSHARP? I have been looking through a number for threads and it seems to be that you need to do a javascript call but I'm unable to find a simple example. Anyone have any experience trying to do this with CEFSHARP?

Below is the code I'm attempting to use to get the height of the HTML document but it doesn't work. I'm fairly sure its the script line that is wrong but cant seem to find the right syntax to just get the document height.
Private Sub WWWBrowser_LoadingState(sender As Object, e As LoadingStateChangedEventArgs) Handles WWWBrowser.LoadingStateChanged
If e.IsLoading = False Then
Dim script = "(function() { var body = document.body, html = document.documentElement; return Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); })();"
Dim task As Task(Of JavascriptResponse) = WWWBrowser.EvaluateScriptAsync(script)
Dim taskResult As String
task.ContinueWith(
Sub(t)
If t.IsFaulted = False Then
Dim response = t.Result 'Error: Result is not a member of Task'
If response.Success And response.Result IsNot Nothing Then
taskResult = response.Result
End If
End If
End Sub)
MsgBox(task.Result.Result)
End If
End Sub

Related

Is there a way to retrieve text from a webpage to a TextBox in VB.NET?

Let say I have a TextBox1 and a SaveButton. A website "www.example.com/code1.text" with just a content:
303981
How to retrieve this 303981 to a TextBox?
Do we need a WebBrowser1?
Please help me I'm self learning and beginner also.
Look at the System.Net.WebClient type.
Using wc As New WebClient()
TextBox1.Text = wc.DownloadString("www.example.com/code1.text")
End Using
You need to place a webbrowser control on your form. I would use CefSharp for this
(see: https://www.youtube.com/watch?v=6d-AgfFzr70)
then you can do something like:
settings = New CefSettings
CefSharp.Cef.Initialize(settings)
browser = New ChromiumWebBrowser("www.google.com")
Which loads google.com, just change it to the page you want to load.
Now check your website and see if you can get that textbox value by javascript from the console (F12). Check the source if you can access it with it's ID or that you need to use it's class.
for example:
document.getElementsByClassName('textboxclass')[0].value;
if you manage to get the right value back in your browser console, you can go ahead in your program and do somethinh like:
Dim task As Task(Of JavascriptResponse) = browser.EvaluateScriptAsync(code)
where code contains your javascript.
you may do something like:
task.ContinueWith(
Sub(t)
Try
If t.IsFaulted = False And t.Result IsNot Nothing Then
Dim response = t.Result 'Error: Result is not a member of Task'
If response.Success And response.Result IsNot Nothing Then
taskResult = response.Result
Else
taskResult = "bad result"
End If
End If
Catch ex As Exception
'Dbg("!!!!!!!!!!!!!!! Exception: " & ex.ToString)
taskResult = ex.ToString
End Try
End Sub)
to get the result in a string.

How to check for strings in a panel?

I'm making a string checker which should check for a string on a website.
I'm using a panel instead of a web browser because I merged chromium with CefSharp into it.
Now I can't figure out how to check for a string in the panel.
I tried creating a different type of variable, but the variable comes from a file.
I also tried for normal text without variables.
Both didn't work.
Public Sub New()
Dim site As String = File.ReadAllText("webstore.shd")
Dim id As String = File.ReadAllText("ID.shd")
InitializeComponent()
Dim settings As New CefSettings()
CefSharp.Cef.Initialize(settings)
browser = New ChromiumWebBrowser(site) With {
.Dock = DockStyle.Fill
}
Panel1.Controls.Add(browser)
If Panel1.Contains(id) Then
' I am stuck right here.
msgbox("Succes")
Else
msgbox("Nope")
End If
End Sub
I expected that the program would search for the variable in the panel, but it wouldn't do that.

Get Recaptcha2 Iframe HTML but always EMPTY using GeckoFX Browser in vb.net

I am using the latest GeckoFX-45 Browser for vb.net.
My problem:
I can not get the HTML of the Iframe.
Here is my code:
'Open Recaptcha2 test site
Browser.Navigate("http://patrickhlauke.github.io/recaptcha/")
'Wait for loading (all ways I know)
Browser.NavigateFinishedNotifier.BlockUntilNavigationFinished()
Dim maxTimeouttime As DateTime = DateTime.Now.AddSeconds(4)
While DateTime.Now < maxTimeouttime
System.Windows.Forms.Application.DoEvents()
System.Threading.Thread.Sleep(100)
End While
While Browser.IsBusy()
System.Windows.Forms.Application.DoEvents()
System.Threading.Thread.Sleep(100)
End While
'Getting the HTML of the Iframe is always empty:
For Each _E As GeckoIFrameElement In Browser.DomDocument.GetElementsByTagName("iframe")
If _E.GetAttribute("title") = "recaptcha widget" Then
Dim html = _E.ContentDocument '-> is empty
Dim html2 = _E.OuterHtml '-> HTML does not include the content of the Iframe
Exit For
End If
Next
The site is displayed very well in the Browser and the recaptcha2 iframe is loaded completly and ready but how can I access it programatically?
Thank you very much
Use ContentWindow.Document instead of ContentDocument.
Your code shoud be:
Dim iFr_dom As GeckoDomDocument
Dim iFr_html As String
For Each iFr As GeckoIFrameElement In Browser.DomDocument.GetElementsByTagName("iframe")
If iFr.GetAttribute("title") = "recaptcha widget" Then
iFr_dom = iFr.ContentWindow.Document
'DomDocument has no OuterHtml property so we use
iFr_html = iFr_dom.GetElementsByTagName("BODY")(0).OuterHtml
'Or if the above not work, use the code below
'iFr_html = iFr_doc.GetElementsByTagName("body")(0).OuterHtml
Exit For
End If
Next

System.UnauthorizedAccessException only using multithreading

I wrote a code to parse some Web tables.
I get some web tables into an IHTMLElementCollection using Internet Explorer with this code:
TabWeb = IE.document.getelementsbytagname("table")
Then I use a sub who gets an object containing the IHTMLElementCollection and some other data:
Private Sub TblParsing(ByVal ArrVal() As Object)
Dim WTab As mshtml.IHTMLElementCollection = ArrVal(0)
'some code
End sub
My issue is: if I simply "call" this code, it works correctly:
Call TblParsing({WTab, LiRow})
but, if I try to run it into a threadpool:
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing), {WTab, LiRow})
the code fails and give me multiple
System.UnauthorizedAccessException
This happens on (each of) these code rows:
Rws = WTab(RifWT("Disc")).Rows.Length
If Not IsError(WTab(6).Cells(1).innertext) Then
Ogg_W = WTab(6).Cells(1).innertext
My goal is to navigate to another web page while my sub perform parsing.
I want to clarify that:
1) I've tryed to send the entire HTML to the sub and get it into a webbrowser but it didn't work because it isn't possible to cast from System.Windows.Forms.HtmlElementCollection to mshtml.IHTMLElementCollection (or I wasn't able to do it);
2) I can't use WebRequest and similar: I'm forced to use InternetExplorer;
3) I can't use System.Windows.Forms.HtmlElementCollection because my parsing code uses Cells, Rows and so on that are unavailable (and I don't want to rewrite all my parsing code)
EDIT:
Ok, I modified my code using answer hints as below:
'This in the caller sub
Dim IE As Object = CreateObject("internetexplorer.application")
'...some code
Dim IE_Body As String = IE.document.body.innerhtml
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing_2), {IE_Body, LiRow})
'...some code
'This is the called sub
Private Sub TblParsing_2(ByVal ArrVal() As Object)
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(ArrVal(0))
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim TabWeb As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
'...some code
I get no errors but I'm not sure that it's all right because I tryed to use IE_Body string into webbrowser and it throws errors in the webpage (it shows a popup and I can ignore errors).
Am I using the right way to get Html from Internet Explorer into a string?
EDIT2:
I changed my code to:
Dim IE As New SHDocVw.InternetExplorer
'... some code
Dim sourceIDoc3 As mshtml.IHTMLDocument3 = CType(IE.Document, mshtml.IHTMLDocument3)
Dim html As String = sourceIDoc3.documentElement.outerHTML
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing_2), {html, LiRow})
'... some code
Private Sub TblParsing_2(ByVal ArrVal() As Object)
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(ArrVal(0))
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim TabWeb As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
But I get an error PopUp like (I tryed to translate it):
Title:
Web page error
Text:
Debug this page?
This page contains errors that might prevent the proper display or function properly.
If you are not testing the web page, click No.
two checkboxes
do not show this message again
Use script debugger built-in Internet Explorer
It's the same error I got trying to get Html text into a WebBrowser.
But, If I could ignore this error, I think the code could work!
While the pop is showing I get error on
Dim domDoc As New mshtml.HTMLDocument
Error text translated is:
Retrieving the COM class factory for component with CLSID {25336920-03F9-11CF-8FD0-00AA00686F13} failed due to the following error: The 8,001,010th message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)).
Note that I've alredy set IE.silent = True
Edit: There was confusion as to what the OP meant by "Internet Explorer". I originally assumed that it meant the WinForm Webbrowser control; however the OP is creating the COM browser directly instead of using the .Net wrapper.
To get the browser document's defining HTML, you can cast the document against the mshtml.IHTMLDocument3 interface to expose the documentElement property.
Dim ie As New SHDocVw.InternetExplorer ' Proj COM Ref: Microsoft Internet Controls
ie.Navigate("some url")
' ... other stuff
Dim sourceIDoc3 As mshtml.IHTMLDocument3 = CType(ie.Document, mshtml.IHTMLDocument3)
Dim html As String = sourceIDoc3.documentElement.outerHTML
End Edit.
The following is based on my comment above. You use the WebBrowser.DocumentText property to create a mshtml.HTMLDocument.
Use this property when you want to manipulate the contents of an HTML page displayed in the WebBrowser control using string processing tools.
Once you extract this property as a String, there is no connection to the WebBrowser control and you can process the data in any thread you want.
Dim html As String = WebBrowser1.DocumentText
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(html)
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim tables As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
' ... do something
' cleanup COM objects
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(body)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(tables)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domDoc)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domDoc2)

Hide Picturebox if image is invalid

I am creating reports using Telerik Reporting Tool and has some image on it. I display the Image in the picturebox using a URL that came from the clients but there are instances where the given URL is invalid so it will display an error message in the report. I want to just hide the picturebox whenever the Image is not available so that the error will not appear in the report. how can I do it? thanks in advance :)
Do a webrequest on your website.
For example:
Public Sub Run()
Dim myReportImage As Image = GetControl("ReportImage")
myReportImage.Visible = CheckWebImage()
' or
myReportImage.Enabled = CheckWebImage()
End Sub
Private Function CheckWebImage() As Boolean
Dim url As New System.Uri("http://www.url.com/yourImage.jpg")
Dim request As System.Net.WebRequest = System.Net.WebRequest.Create(url)
Dim response As System.Net.WebResponse
Try
response = req.GetResponse()
response.Close()
request = Nothing
Msgbox("Website Found!")
Return True
Catch ex As Exception
request = Nothing
Msgbox("Website not found. Check the url and internet connection")
Return False
End Try
End Sub