Operating on a web page using the Document Object - vb.net

I have a VB.Net app that needs to print a bunch of pages from a secure intranet site; the app was made and was working for a non-secure site but now the app needs to login before accessing the web pages necessary to print.
I get the error "Object Reference not set to an instance of an object" when I use my new Sub which follows:
Private Sub SiteLogin()
WebBrowser1.Navigate("http://url/login/")
WebBrowser1.Document.GetElementById("user").SetAttribute("value", "username")
WebBrowser1.Document.GetElementById("password").SetAttribute("value", "mypassword")
WebBrowser1.Document.GetElementById("submit").InvokeMember("click")
End Sub
I got the code from this VB tutorial, but I seem to be missing something in how I'm referencing the WebBrowser.Document object. I've never used VB.Net before so I don't know much about this problem, I have the following sub which DOES work from the original program however:
Private Sub WebPrint()
WebBrowser1.Navigate(strUrl)
WebDocLoaded = False
'lblMessage.Text = "Waiting for report page to load"
Do Until WebDocLoaded
System.Windows.Forms.Application.DoEvents()
Loop
End Sub
This Sub prints the given page in IE, so I figured I could use the same WebBrowser1 object for the login Sub, as I don't know how to or whether I should declare a separate object for the SiteLogin Sub. Both of these functions are called after the WebBrowser1 object is defined however.
I just need to be able to submit a simple login form to a set URL, and this info needs to all be hardcoded (there's no option to set the location or login info nor should there be). If there's another way to log into this site via VB.Net or if I need to give more information let me know.

.Navigate returns before the page load is complete so the DOM is not ready & .Document is not accessible.
See; How to wait until WebBrowser is completely loaded in VB.NET?

Related

Automatic login when run the program second time

Recently try to use a webbrowser component.
when I click button, it will navigate to facebook.com. after I login on first time and stop the program. and then when I run the program second time I don't need to fill the email and password. why I don't need to fill an email and password textbox ? thanks
Here's the code
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
WebBrowser1.Navigate("m.facebook.com")
End Sub
End Class
Note: I will delete this post, because it doesn't help the community. Just my curiosity. Thanks
how do i need to re-type the email password again when 2nd starting the program
You have two options:
The first is to save the CookieContainer associated with the WebBrowser to disk and reload it when you restart your program. There is no straightforward way to serialize cookies to disk or other storage method - that is up to you.
Instruct the WebBrowser object to make use of the user's Windows profile Internet Explorer cookie collection which is shared with Internet Explorer and other programs that also opt-in to sharing state (I do not know if this also applies to the Edge browser, I suspect it does not). See here for instructions on how to do this: Use cookies from CookieContainer in WebBrowser

Winform controls loaded from CefSharp causing Cross-Thread errors

I'm integrating CefSharp into a legacy Winforms application. Currently the application uses the default .NET browser control. Unfortunately, this control has a memory leak which is causing serious problems. I'm trying to get the CefSharp browser integrated without major refactoring, since the application is scheduled to be retired later this year and replaced with a new WPF application.
So far, I'm able to make CefSharp work in most scenarios. Standard webpages open without a problem. However, some of these pages have specially formed links which, when interpretted by the application, open up .Net forms instead of other webpages. This is where I run into an issue. When the webpage opened in CefSharp calls one of these links and the application attempts to open the new form, it appears to be doing so on the thread hosting the CefSharp instance, which is different from that hosting the application itself. This leads to numerous cross-thread issues (the legacy application in question isn't particularly well architectured). I'm trying to find a way to solve this issue without rearchitecturing the Winform application.
The following is a brief example of the situation.
Controls
frmMain
This is the primary form on the application. It has a number of duties, but the one pertinent to the current situation is that it hosts a Telerik DocumentTabStrip which contains the application's "tabs" (each browser or form opens within one of these tabs). It also contains the method that is used to load the various form or browser controls that are instantiated and add them to the aforementioned DocumentTabStrip.
ucChromeBrowser
This is the object which wraps the CefSharp browser instances which get created. It also has all the Event Handlers for the CefSharp events, such as IRequestHandler, ILifespanHandler, IContextMenuHandler, etc.
EntryScreens.uc_Foo
This is one of the Winform controls that are called from the webpage hosted in ucChromeBrowser. A typical link looks like WEB2WIN:Entryscreens.uc_Foo?AdditionalParameterDataHere. We intercept these calls in frmMain and instead of attempting to open the link in a browser, we instantiate a new instance of EntryScreen.uc_Foo and load that new form into frmMain.DocumentTabStrip as follows.
Dim _DockWindow As Telerik.WinControls.UI.Docking.DocumentWindow = Nothing
Dim _Control As ucBaseControl = Nothing
Dim _WebBrowser As ucBrowser = Nothing
Dim _isWebBrowerLink As Boolean = False
'Do Other Stuff here, such as instantiating the _Control or _WebBrowser instance, setting _isWebBrowserLink, etc.
_DockWindow = New Telerik.WinControls.UI.Docking.DocumentWindow
If _isWebBrowerLink Then
If Not IsNothing(_WebBrowser) Then
_WebBrowser.Dock = DockStyle.Fill
_DockWindow.Controls.Add(_WebBrowser)
End If
Else
_Control.Dock = DockStyle.Fill
_DockWindow.Controls.Add(_Control)
End If
DocumentTabStrip.InvokeIfRequired(Sub() DocumentTabStrip.Controls.Add(_DockWindow))
(In case it matters, here's the InvokeIfRequired method I'm calling.)
Public Module ISynchronizeInvokeExtensions
<Runtime.CompilerServices.Extension>
Public Sub InvokeIfRequired(obj As ISynchronizeInvoke, action As MethodInvoker)
Dim idleCounter As Integer = 0
While Not CType(obj, Control).Visible
'Attempt to sleep since there's no visible control
If idleCounter < 5 Then
Threading.Thread.Sleep(50)
Else
Exit While
End If
End While
If obj.InvokeRequired Then
Dim args = New Object(-1) {}
obj.Invoke(action, args)
Else
action()
End If
End Sub
End Module
The issue comes up when trying to call DocumentTabStrip.InvokeIfRequired(Sub() DocumentTabStrip.Controls.Add(_DockWindow)). From what I can tell, it appears that this changes the layout of the controls hosted within, causing various controls to be instantiated or to have their events called. This, in turn, causes an InvalidOperationException (e.g.: "Cross-thread operation not valid: Control 'pnlLoading' accessed from a thread other than the thread it was created on."). The specific child control varies from Form to Form (so for Form A it might always be pnlLoading which causes it, but for another Form it might be a different control). But most or all of them exhibit this behavior. I have no doubt it's due to the controls themselves being poorly designed, but I don't really have the time to refactor all of them.
So that's the situation. It appears as though the multi-threaded nature of CefSharp is conflicting with the single-threaded nature of the controls in question and causing them to get called on a different thread than they would be otherwise. Is there a way to prevent this?
Controls should only be created on the UI thread, and not in background threads. The error message tells you pretty clearly what's going on.
Cross-thread operation not valid: Control 'pnlLoading' accessed from a thread other than the thread it was created on.
You are accessing the control from the UI thread but due to that it is actually created in a background thread you are performing a cross-thread access since you're invoking to the wrong thread.
Whatever you do you would almost always have to invoke to the background thread when accessing the control, but you cannot do this for any automatic access done by, for instance, the UI message loop.
Therefore you should put all control creation and accessing in the UI only, thus meaning you must put all that code in your first code block in an invoke.
DocumentTabStrip.InvokeIfRequired( _
Sub()
Dim _DockWindow As Telerik.WinControls.UI.Docking.DocumentWindow = Nothing
Dim _Control As ucBaseControl = Nothing
Dim _WebBrowser As ucBrowser = Nothing
Dim _isWebBrowerLink As Boolean = False
'Do Other Stuff here, such as instantiating the _Control or _WebBrowser instance, setting _isWebBrowserLink, etc.
_DockWindow = New Telerik.WinControls.UI.Docking.DocumentWindow
If _isWebBrowerLink Then
If Not IsNothing(_WebBrowser) Then
_WebBrowser.Dock = DockStyle.Fill
_DockWindow.Controls.Add(_WebBrowser)
End If
Else
_Control.Dock = DockStyle.Fill
_DockWindow.Controls.Add(_Control)
End If
DocumentTabStrip.Controls.Add(_DockWindow)
End Sub)

VB6 Application ODBC Error

I have a VB6 application working with.
This application uses ODBC to access a Microsoft Access database.
I am sure that the database string is correct as the database contains the information used to login and the login works just fine. I also have the same string at every instance.
However, at a certain point the ODBC driver error-"Data source name not found and no default driver specified" appears...The issue is:
This occurs whenever I press a specific button. This button opens a form:
Private sub Munubttn_Click()
frmLog.Show
End Sub
However, in the form frmLog, I placed a message box as the first command under the Form_Load() sub. Now whenever the button is clicked, I get the error, just before the message box. As such, I do not know where this error originates. So I suppose the question is, what code does the form execute just before it loads? Any help would be appreciated.
So I suppose the question is, what code does the form execute just before it loads?
The only code that would be executed would be the class initialize sub. Given your described scenario, the problematic logic is likely in a Class_Initialize sub within the frmLog Form.

using ppDisp to take control of popup windows in userform

I have setup a userform1 to browse an intranet using web browser controls in VBA/Excel. The problem I am having is that when the user initiates a popup through the web browser control, that popup runs in IE by default, outside of the scope of the web browser control, and therefore doesnt contain the correct session data in the popup. This popup initiates from a dropdown box, onchange command and then inserts the input from the popup back into a web form on the page. The code below intercepts the popup event and lets you handle it, by transferring it to say, userform2
Private Sub WebBrowser1_NewWindow2(ppDisp As Object, Cancel As Boolean)
Dim frm As UserForm2
'Dim ppDisp As Object
Set frm = New UserForm2
Set ppDisp = frm.WebBrowser1.Application
frm.Show
End Sub
Problem is, it gets stuck right now on frm.show, when I pause, and doesnt seem to be actively transferring over the web page correctly into userform2. I'm not sure where my logic is wrong here, any advice would be helpful. Most guides have shown:
Set ppDisp = frm.WebBrowser1.object
But I cant find that in the object browser anywhere, and doing .object bombs out, as error 438: object doesnt support this property or method. But everything I could find on this so far shows using .object.
for anyone reading this, VBA wont support this method as the above says. It works perfectly in .net and I would assume then, vb6

Windows Mobile SDK : how to turn a label/button into a website link?

I am programming in Windows Mobile SDK 6 using Visual Basic, i would like to know how to make a button open the smartphone browser with a specific website path (make a link)
I got to the next piece of code so far:
Public Class GuitarHelperPage
Public link As New WebBrowser
Public adress As Uri
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
adress = New Uri("https://www.google.com")
Try
link.Navigate(adress)
'link.Focus()
Catch ex As System.UriFormatException
Return
End Try
End Sub
(the commented 'link.Focus()' its just something i tryed out, but i got the same output)
I simply want to click the button and open the browser at google homepage. But when I click it, the warning "This page contains both secure and nonsecure items. Do you want to continue?" appears and when I click "yes", nothing else hapens.
I've been researching and found this on MSDN help pages:
"The WebBrowser class can only be used in threads set to single thread apartment (STA) mode. To use this class, ensure that your Main method is marked with the STAThreadAttribute attribute"
SO i added this my main method:
<STAThread()> _
Shared Sub Main()
But still i get this error : "Type STAThread is not defined." And can't find a away around, I tried to add this same attribute to a Windows Desktop VB project and it works, maybe there is another way to do it in Mobile?
I am using .Net Framework 3.5 and windows mobile sdk 6.0 for this project
Please help, thank you.
If you want to open the default browser, you don't need a WebBrowser control. Just use the Process class, specifically the Start overload that takes in a ProcessStartInfo. Set the UseShellExecute property of the ProcessStartInfo to true so that it will open the default browser (e.g. if the user installed Opera Mobile, it will use that, not just always force IE).