I have a sendmail program in vb.net. I have attachments sending just fine. The problem is when there is NO ATTACHMENT, the program errors out. How do i handle no attachment to bypass and send with no attachment? The below works fine.
Yea yea i know, my naming convention is horrible. I will change once i have the logic 100% complete.
Imports System.Net.Mail
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If TextBox1.Text = "" Then
MsgBox("Please describe the issue you're having Bender, I'm not a mindreader!")
Exit Sub
Else
lblpleasewait.Visible = True
Delay(2000)
Dim Recipients As New List(Of String)
Recipients.Add("emtnap6#yahoo.com")
Dim FromEmailAddress As String = Recipients(0)
Dim Subject As String = "IT Help!"
Dim Body As String = TextBox1.Text
Dim UserName As String = "fakeout"
Dim Password As String = "fakeout"
Dim Port As Integer = 587
Dim Server As String = "smtp.gmail.com"
Dim Attachments As New List(Of String)
MsgBox(SendEmail(Recipients, FromEmailAddress, Subject, Body, UserName, Password, Server, Port, Attachments))
TextBox2.Text = "Attach Screenshot:"
TextBox2.TextAlign = HorizontalAlignment.Right
lblpleasewait.Visible = False
TextBox1.Text = ""
TextBox1.Focus()
End If
End Sub
Sub delay(ByVal delay_ms As Integer)
Dim tspan As New TimeSpan
Dim tstart = Now
While tspan.TotalMilliseconds < delay_ms
tspan = Now - tstart
Application.DoEvents()
End While
End Sub
Function SendEmail(ByVal Recipients As List(Of String), _
ByVal FromAddress As String, _
ByVal Subject As String, _
ByVal Body As String, _
ByVal UserName As String, _
ByVal Password As String, _
Optional ByVal Server As String = "smtp.gmail.com", _
Optional ByVal Port As Integer = 587, _
Optional ByVal Attachments As List(Of String) = Nothing) As String
Dim Email As New MailMessage()
Try
Dim SMTPServer As New SmtpClient
''For Each Attachment As String In Attachments
'' Email.Attachments.Add(New Attachment(Attachment))
'Next
Dim mailattach As String = TextBox2.Text
Dim attachment As System.Net.Mail.Attachment
attachment = New System.Net.Mail.Attachment(mailattach)
Email.Attachments.Add(attachment)
Email.From = New MailAddress(FromAddress)
For Each Recipient As String In Recipients
Email.Bcc.Add(Recipient)
Next
Email.Subject = Subject
Email.Body = Body
SMTPServer.Host = Server
SMTPServer.Port = Port
SMTPServer.Credentials = New System.Net.NetworkCredential(UserName, Password)
SMTPServer.EnableSsl = True
SMTPServer.Send(Email)
Email.Dispose()
Return "Email to Derek was successfully sent."
Catch ex As SmtpException
Email.Dispose()
Return "Sending Email Failed. Smtp Error."
Catch ex As ArgumentOutOfRangeException
Email.Dispose()
Return "Sending Email Failed. Check Port Number."
Catch Ex As InvalidOperationException
Email.Dispose()
Return "Sending Email Failed. Check Port Number."
End Try
End Function
Private Sub FolderBrowserDialog1_HelpRequest(sender As Object, e As EventArgs)
If (FolderBrowserDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
TextBox2.Text = FolderBrowserDialog1.SelectedPath
End If
End Sub
Private Sub Button2_Click(sender As Object, e As System.EventArgs) Handles Button2.Click
OpenFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
If (OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
TextBox2.Text = OpenFileDialog1.FileName
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1.Focus()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
If Not Environment.Is64BitProcess Then
Process.Start("C:\Windows\sysnative\SnippingTool.exe")
Else
Process.Start("C:\Windows\system32\SnippingTool.exe")
End If
End Sub
Private Sub OpenFileDialog1_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
OpenFileDialog1.InitialDirectory = Environment.SpecialFolder.MyComputer
End Sub
End Class
This should solve the problem.
If TextBox2.text <> "" then
Dim mailattach As String = TextBox2.Text
Dim attachment As System.Net.Mail.Attachment
attachment = New System.Net.Mail.Attachment(mailattach)
Email.Attachments.Add(attachment)
End if
Related
I have a Windows Forms app in Visual basic that is currently sending messages back and forth between two computers. Currently, the user has to manually enter the ipv4 address of the receiver of the message. what I would like to do is put the ipv4 addresses of all the computers on the network into a combo box so the user has a list to pick from.
I have searched a whole bunch of different forums and am unable to find a working solution.
Public Class Form1
Dim strHostName As String
Dim strIPAddress As String
Dim running As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
strHostName = System.Net.Dns.GetHostName()
strIPAddress = System.Net.Dns.GetHostByName(strHostName).AddressList(0).ToString()
Me.Text = strIPAddress
txtIP.Text = strIPAddress
running = True
'run listener on separate thread
Dim listenTrd As Thread
listenTrd = New Thread(AddressOf StartServer)
listenTrd.IsBackground = True
listenTrd.Start()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As EventArgs) Handles MyBase.FormClosing
running = False
End Sub
Sub StartServer()
Dim serverSocket As New TcpListener(CInt(txtPort.Text))
Dim requestCount As Integer
Dim clientSocket As TcpClient
Dim messageReceived As Boolean = False
While running
messageReceived = False
serverSocket.Start()
msg("Server Started")
clientSocket = serverSocket.AcceptTcpClient()
msg("Accept connection from client")
requestCount = 0
While (Not (messageReceived))
Try
requestCount = requestCount + 1
Dim networkStream As NetworkStream = clientSocket.GetStream()
Dim bytesFrom(10024) As Byte
networkStream.Read(bytesFrom, 0, bytesFrom.Length)
Dim dataFromClient As String = System.Text.Encoding.ASCII.GetString(bytesFrom)
dataFromClient = dataFromClient.Substring(0, dataFromClient.Length)
'invoke into other thread
txtOut.Invoke(Sub()
txtOut.Text += dataFromClient
txtOut.Text += vbNewLine
End Sub)
messageReceived = True
Dim serverResponse As String = "Server response " + Convert.ToString(requestCount)
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(serverResponse)
networkStream.Write(sendBytes, 0, sendBytes.Length)
networkStream.Flush()
Catch ex As Exception
End
End Try
End While
clientSocket.Close()
serverSocket.Stop()
msg("exit")
Console.ReadLine()
End While
End Sub
Sub msg(ByVal mesg As String)
mesg.Trim()
Console.WriteLine(" >> " + mesg)
End Sub
Public Sub WriteData(ByVal data As String, ByRef IP As String)
Try
txtOut.Text += data.PadRight(1)
txtOut.Text += vbNewLine
txtMsg.Clear()
Console.WriteLine("Sending message """ & data & """ to " & IP)
Dim client As TcpClient = New TcpClient()
client.Connect(New IPEndPoint(IPAddress.Parse(IP), CInt(txtPort.Text)))
Dim stream As NetworkStream = client.GetStream()
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes(data)
stream.Write(sendBytes, 0, sendBytes.Length)
Catch ex As Exception
msg(ex.ToString)
End Try
End Sub
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
If Not (txtMsg.Text = vbNullString) AndAlso Not (txtIP.Text = vbNullString) Then
WriteData(txtMsg.Text, txtIP.Text)
End If
End Sub
Private Sub txtMsg_KeyDown(sender As Object, e As KeyEventArgs) Handles txtMsg.KeyDown
If e.KeyCode = Keys.Enter Then
If Not (txtMsg.Text = vbNullString) AndAlso Not (txtIP.Text = vbNullString) Then
WriteData(txtMsg.Text, txtIP.Text)
End If
End If
End Sub
Private Sub BtnFind_Click(sender As Object, e As EventArgs) Handles btnFind.Click
'find all local addresses and put in combobox (button will be removed later)
End Sub
End Class
For PC names "as you suggested in your comments", I used this at work to get pc names i was on domain, try it:
AFAIK it works on domains...
Make sure you have a listbox on your form, or change listbox and populate in your combobox directly, play with that as you like :)
Private Delegate Sub UpdateDelegate(ByVal s As String)
Dim t As New Threading.Thread(AddressOf GetNetworkComputers)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
t.IsBackground = True
t.Start()
End Sub
Private Sub AddListBoxItem(ByVal s As String)
ListBox1.Items.Add(s)
End Sub
Private Sub GetNetworkComputers()
Try
Dim alWorkGroups As New ArrayList
Dim de As New DirectoryEntry
de.Path = "WinNT:"
For Each d As DirectoryEntry In de.Children
If d.SchemaClassName = "Domain" Then alWorkGroups.Add(d.Name)
d.Dispose()
Next
For Each workgroup As String In alWorkGroups
de.Path = "WinNT://" & workgroup
For Each d As DirectoryEntry In de.Children
If d.SchemaClassName = "Computer" Then
Dim del As UpdateDelegate = AddressOf AddListBoxItem
Me.Invoke(del, d.Name)
End If
d.Dispose()
Next
Next
Catch ex As Exception
'MsgBox(Ex.Message)
End Try
End Sub
POC:
I'm trying to get the IP address of the connected client but I don't know what I doing wrong. Where I can find it? I think near Sub AcceptClient. I was trying to convert cClient to string, but it always results to True or False. I'm trying to get the argument ar from cClient, which gives me an empty result.
Client.Client.RemoteEndPoint doesn't work or I can't use it correctly.
Form1.vb from Server project
Imports System.IO, System.Net, System.Net.Sockets
Public Class Form1
Dim Listener As TcpListener
Dim Client As TcpClient
Dim ClientList As New List(Of ChatClient)
Dim sReader As StreamReader
Dim cClient As ChatClient
Sub xLoad() Handles Me.Load
Listener = New TcpListener(IPAddress.Any, 3818)
Timer1.Start()
Listener.Start()
xUpdate("Server Started", False)
Listener.BeginAcceptTcpClient(New AsyncCallback(AddressOf AcceptClient), Listener)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
''Set view property
ListView1.View = View.Details
ListView1.GridLines = True
ListView1.FullRowSelect = True
'Add column header
ListView1.Columns.Add("Adres IP", 120)
ListView1.Columns.Add("Nazwa użytkownika", 120)
End Sub
Sub AcceptClient(ByVal ar As IAsyncResult)
cClient = New ChatClient(Listener.EndAcceptTcpClient(ar))
AddHandler(cClient.MessageRecieved), AddressOf MessageRecieved
AddHandler(cClient.ClientExited), AddressOf ClientExited
ClientList.Add(cClient)
xUpdate("New Client Joined", True)
Listener.BeginAcceptTcpClient(New AsyncCallback(AddressOf AcceptClient), Listener)
End Sub
Sub MessageRecieved(ByVal Str As String)
xUpdate(Str, True)
End Sub
Sub ClientExited(ByVal Client As ChatClient)
ClientList.Remove(Client)
xUpdate("Client Exited", True)
End Sub
Delegate Sub _xUpdate(ByVal Str As String, ByVal Relay As Boolean)
Sub xUpdate(ByVal Str As String, ByVal Relay As Boolean)
On Error Resume Next
If InvokeRequired Then
Invoke(New _xUpdate(AddressOf xUpdate), Str, Relay)
Else
Dim nStart As Integer
Dim nLast As Integer
If Str.Contains("</>") Then
nStart = InStr(Str, "</></>") + 7
nLast = InStr(Str, "<\><\>")
Str = Mid(Str, nStart, nLast - nStart)
'dzielenie strina po odpowiednim syymbolu na przed i po symbolu :D
Dim mystr As String = Str
Dim cut_at As String = ","
Dim x As Integer = InStr(mystr, cut_at)
Dim string_before As String = mystr.Substring(0, x - 1)
Dim string_after As String = mystr.Substring(x + cut_at.Length - 1)
Dim otherItems As String() = {string_after}
ListView1.Items.Add(string_before).SubItems.AddRange(otherItems) 'use SubItems
ElseIf Str.Contains("<A>") Then
nStart = InStr(Str, "<A>") + 4
nLast = InStr(Str, "<B>")
Str = Mid(Str, nStart, nLast - nStart)
ListBox2.Items.Add(Str & vbNewLine)
Else
TextBox1.AppendText(Str & vbNewLine)
If Relay Then Send(Str & vbNewLine)
End If
End If
End Sub
Private Sub TextBox2_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox2.KeyDown
If e.KeyCode = Keys.Enter Then
e.SuppressKeyPress = True
xUpdate("Server Says: " & TextBox2.Text, True)
TextBox2.Clear()
End If
End Sub
Sub Send(ByVal Str As String)
For i As Integer = 0 To ClientList.Count - 1
Try
ClientList(i).Send(Str)
Catch
ClientList.RemoveAt(i)
End Try
Next
End Sub
End Class
ChatClient.vb from Server project
Imports System.Net.Sockets, System.IO
Public Class ChatClient
Public Event MessageRecieved(ByVal Str As String)
Public Event ClientExited(ByVal Client As ChatClient)
Private sWriter As StreamWriter
Public Client As TcpClient
Sub New(ByVal xclient As TcpClient)
Client = xclient
client.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Read, Nothing)
End Sub
Private Sub Read()
Try
Dim sr As New StreamReader(Client.GetStream)
Dim msg As String = sr.ReadLine()
RaiseEvent MessageRecieved(msg)
Client.GetStream.BeginRead(New Byte() {0}, 0, 0, New AsyncCallback(AddressOf Read), Nothing)
Catch
RaiseEvent ClientExited(Me)
End Try
End Sub
Public Sub Send(ByVal Message As String)
sWriter = New StreamWriter(Client.GetStream)
sWriter.WriteLine(Message)
sWriter.Flush()
End Sub
End Class
You can get the IP address from the underlying socket by converting the Socket.RemoteEndPoint property into an IPEndPoint:
Dim Address As IPAddress = CType(cClient.Client.Client.RemoteEndPoint, IPEndPoint).Address
MessageBox.Show(Address.ToString()) 'Example.
I have made an E-mailer like program. When I start it, it gives me this Error message:
An unhandled exception of type 'System.InvalidOperationException' occurred in Menü (VB Version 1.0).exe
My Code
Imports System.Net.Mail
Public Class Email
Dim Tárgy As String = TextBox4.Text
Dim Üzenet As String = TextBox5.Text
Dim UserEmail As String = TextBox1.Text
Dim UserPass As String = TextBox2.Text
Dim ToEmail As String = TextBox3.Text
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim MyMailMessage As New MailMessage()
Try
MyMailMessage.From = New MailAddress(UserEmail)
MyMailMessage.To.Add(ToEmail)
MyMailMessage.Subject = (Tárgy)
MyMailMessage.Body = (Üzenet)
Dim SMTP As New SmtpClient("smtp.gmail.com")
SMTP.Port = 587
SMTP.EnableSsl = True
SMTP.Credentials = New System.Net.NetworkCredential((UserEmail), (UserPass))
SMTP.Send(MyMailMessage)
Catch ex As Exception
End Try
End Sub
End Class
Move the initialization of your strings inside the Click event. You don't need them before and doing it at the global level will cause an exception because the TextBoxes and other controls are not yet initialized
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Tárgy As String = TextBox4.Text
Dim Üzenet As String = TextBox5.Text
Dim UserEmail As String = TextBox1.Text
Dim UserPass As String = TextBox2.Text
Dim ToEmail As String = TextBox3.Text
Dim MyMailMessage As New MailMessage()
....
SMTP.Send(MyMailMessage)
End Sub
Also, if you don't do anything with the exception then do not use empty trt/catch blocks. If an exception occurs then you can't see the error.
i have 3 text boxes and a combo box i have to give the server name,username and password in the text boxes and the combo box should display the database names.Please help me
Can we assume that, when you tagged this question with sql you actually mean that the database is SQL Server? If so then, to get a list of databases attached to an instance, create a SqlConnection with an appropriate connection string but no value for Initial Catalog. You can then call GetSchema on that connection and specify "Databases" as the collection. That will return a DataTable containing data about the databases. The names of the databases will be in the "database_name" column. Here's some code that I used for a dialogue where the user entered connection details like you're doing:
Public Class OptionsDialogue
Private populateServerList As Boolean = True
Private populateDatabaseList As Boolean = True
Private Sub OptionsDialogue_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles MyBase.Load
Me.LoadConnectionString()
'Me.LoadAppSettings()
End Sub
Private Sub serverCombo_DropDown(ByVal sender As Object, ByVal e As System.EventArgs) Handles serverCombo.DropDown
If Me.populateServerList Then
'Enumerate available SQL Server instances.
Dim serverTable As DataTable = SqlDataSourceEnumerator.Instance.GetDataSources()
Dim upperBound As Integer = serverTable.Rows.Count - 1
Dim serverNames(upperBound) As String
For index As Integer = 0 To upperBound
If serverTable.Rows(index).IsNull("InstanceName") Then
serverNames(index) = CStr(serverTable.Rows(index)("ServerName"))
Else
serverNames(index) = String.Format("{0}\{1}", _
serverTable.Rows(index)("ServerName"), _
serverTable.Rows(index)("InstanceName"))
End If
Next
Dim currentServerName As String = Me.serverCombo.Text
With Me.serverCombo
.BeginUpdate()
.Items.Clear()
.Items.AddRange(serverNames)
.SelectedItem = currentServerName
.Text = currentServerName
.EndUpdate()
End With
Me.populateServerList = False
End If
End Sub
Private Sub sqlServerSecurityOption_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles sqlServerSecurityOption.CheckedChanged
Dim sqlServerSecurity As Boolean = Me.sqlServerSecurityOption.Checked
Me.userLabel.Enabled = sqlServerSecurity
Me.userText.Enabled = sqlServerSecurity
Me.passwordLabel.Enabled = sqlServerSecurity
Me.passwordText.Enabled = sqlServerSecurity
End Sub
Private Sub databaseCombo_DropDown(ByVal sender As Object, ByVal e As System.EventArgs) Handles databaseCombo.DropDown
Using connection As New SqlConnection(Me.GetConnectionString(False))
Try
connection.Open()
'Enumerate available databases.
Me.databaseCombo.DataSource = connection.GetSchema("Databases")
Catch
MessageBox.Show("Unable to connect.", _
"Connection Error", _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
End Try
End Using
End Sub
Private Sub testButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles testButton.Click
If Me.TestConnection() Then
MessageBox.Show("Connection successful.", _
"Connection Successful", _
MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Else
MessageBox.Show("Connection failed.", _
"Connection Failed", _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
End If
End Sub
Private Sub okButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles okButton.Click
If Me.TestConnection() OrElse _
MessageBox.Show("A connection could not be established using the specified settings." & _
Environment.NewLine & _
"Do you still want to save the connection settings?", _
"Connection Failed", _
MessageBoxButtons.OKCancel, _
MessageBoxIcon.Warning, _
MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.OK Then
Dim configSaved As Boolean
configSaved = Me.SaveConnectionString
'configSaved = Me.SaveAppSettings
If configSaved OrElse _
MessageBox.Show("The connection settings could not be saved." & _
Environment.NewLine & _
"Do you still want to close the window?", _
"Save Failed", _
MessageBoxButtons.OKCancel, _
MessageBoxIcon.Error, _
MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.OK Then
Me.DialogResult = Windows.Forms.DialogResult.OK
End If
End If
End Sub
Private Sub LoadConnectionString()
'Load the current connection string.
Dim builder As New SqlConnectionStringBuilder(My.Settings.PrimaryConnectionString)
'Display individual connection string properties.
Me.serverCombo.Text = builder.DataSource
Me.integratedSecurityOption.Checked = builder.IntegratedSecurity
Me.sqlServerSecurityOption.Checked = Not builder.IntegratedSecurity
Me.userText.Text = builder.UserID
Me.passwordText.Text = builder.Password
Me.databaseCombo.Text = builder.InitialCatalog
End Sub
Private Sub LoadAppSettings()
'Open the primary config file.
Dim config As System.Configuration.Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
Dim appSettings As KeyValueConfigurationCollection = config.AppSettings.Settings
Dim osSecurity As Boolean
Boolean.TryParse(appSettings("OSSecurity").Value, osSecurity)
'Display individual connection string properties.
Me.serverCombo.Text = appSettings("ServerName").Value
Me.integratedSecurityOption.Checked = osSecurity
Me.sqlServerSecurityOption.Checked = Not osSecurity
Me.userText.Text = appSettings("UserName").Value
Me.passwordText.Text = appSettings("Password").Value
Me.databaseCombo.Text = appSettings("DatabaseName").Value
End Sub
Private Function GetConnectionString(ByVal includeDatabase As Boolean) As String
Dim builder As New SqlConnectionStringBuilder()
'Build a connection string from the user input.
builder.DataSource = Me.serverCombo.Text
builder.IntegratedSecurity = Me.integratedSecurityOption.Checked
builder.UserID = Me.userText.Text
builder.Password = Me.passwordText.Text
If includeDatabase Then
builder.InitialCatalog = Me.databaseCombo.Text
End If
Return builder.ConnectionString
End Function
Private Function TestConnection() As Boolean
Dim result As Boolean = False
Using connection As New SqlConnection(Me.GetConnectionString(True))
Try
connection.Open()
result = True
Catch
End Try
End Using
Return result
End Function
Private Function SaveConnectionString() As Boolean
Dim result As Boolean = False
'Open the primary config file.
Dim config As System.Configuration.Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
For Each setting As ConnectionStringSettings In config.ConnectionStrings.ConnectionStrings
'Find the desired connection string.
If setting.Name.Contains("PrimaryConnectionString") Then
'Update the connection string from the user input.
setting.ConnectionString = Me.GetConnectionString(True)
'Save the changes to the config file.
config.Save(ConfigurationSaveMode.Modified)
ConfigurationManager.RefreshSection("connectionStrings")
'Force the connection string to reload the new value from the config file.
My.Settings.Reload()
result = True
Exit For
End If
Next setting
Return result
End Function
Private Function SaveAppSettings() As Boolean
Dim result As Boolean = False
'Open the primary config file.
Dim config As System.Configuration.Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
Dim appSettings As KeyValueConfigurationCollection = config.AppSettings.Settings
appSettings("ServerName").Value = Me.serverCombo.Text
appSettings("DatabaseName").Value = Me.databaseCombo.Text
appSettings("OSSecurity").Value = Me.integratedSecurityOption.Checked.ToString()
appSettings("UserName").Value = Me.userText.Text
appSettings("Password").Value = Me.passwordText.Text
'Save the changes to the config file.
config.Save(ConfigurationSaveMode.Modified)
ConfigurationManager.RefreshSection("appSettings")
result = True
Return result
End Function
End Class
I am a bit of a noobie with vb.net and I made this application that does a lot of http requests and stream reading. But when it does this it always freezes my application.
So I did a little research and found that I could use background workers to solve this. But I have no idea where to start. So if you could look at my code and tell me where and how I can add background workers to prevent the freezing that would be awesome.
Imports mshtml
Imports System.Net
Imports System.Threading
Imports System.Text
Imports System.IO
Imports System.Web
Public Class Form1
Inherits Form
Private Delegate Sub MyDelegate(show As Boolean)
Private demoThread As System.Threading.Thread = Nothing
Private demoThread2 As System.Threading.Thread = Nothing
Private Sub ShowProgressOnThread()
Dim newProgressWindow As New Form2
newProgressWindow.Show()
End Sub
Public Function GetTableText(ByVal sHTML As String) As String
Dim myDoc As mshtml.IHTMLDocument2 = New mshtml.HTMLDocument
Dim mElement As mshtml.IHTMLElement
Dim mElement2 As mshtml.IHTMLElement
Dim mECol As mshtml.IHTMLElementCollection
'initialize the document object within the HTMLDocument class...
myDoc.close()
myDoc.open("about:blank")
'write the HTML to the document using the MSHTML "write" method...
Dim clsHTML() As Object = {sHTML}
myDoc.write(clsHTML)
clsHTML = Nothing
mElement = myDoc.body()
mECol = mElement.getElementsByTagName("TD")
Dim gData As ListViewItem
For A = 3 To mECol.length - 1 Step +6
mElement2 = mECol.item(A)
gData = Me.ListView1.Items.Add(mElement2.innerText)
mElement2 = mECol.item(A - 1)
gData.SubItems.Add(mElement2.innerText.ToUpper)
'Frm.Close()
' lstResults.Items.Add("Game : " & mElement2.innerText)
Next
End Function
Private Sub wait(ByVal interval As Integer)
Dim sw As New Stopwatch
sw.Start()
Do While sw.ElapsedMilliseconds < interval
' Allows UI to remain responsive
Application.DoEvents()
Loop
sw.Stop()
End Sub
Private Sub Button__()
Me.ResetText()
Me.ToolStripStatusLabel1.Text = "Loading..."
Me.Text = "Game Finder | By Unh0ly | Loading..."
' Me.demoThread = New Thread( _
'New ThreadStart(AddressOf Me.Loader))
' Me.demoThread.Start()
'Me.Invoke(New MethodInvoker(AddressOf Me.Loader))
'Me.Frm.Show()
'Application.Run(Frm)
Dim srchText As String
srchText = TextBox1.Text.Replace(" ", "%20")
Dim request As HttpWebRequest = HttpWebRequest.Create("****" & srchText)
'Dim response As HttpWebResponse
Dim response As HttpWebResponse = request.GetResponse()
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(response.GetResponseStream())
Dim sourcecode As String = sr.ReadToEnd()
If sourcecode.Contains("<td>") Then
GetTableText(sourcecode)
Me.ResetText()
Me.Text = "Game Finder | By Unh0ly"
Me.ToolStripStatusLabel1.Text = "Done"
Call wait(2500)
Me.ToolStripStatusLabel1.Text = "Status.."
'newProgressWindow.Hide()
'newProgressWindow.Dispose()
'Form2.Refresh()
ElseIf Not sourcecode.Contains("<td>") Then
' newProgressWindow.Hide()
' Progress.Dispose()
MessageBox.Show("No Results Found For: " + TextBox1.Text)
End If
'Dim sHTML = sourcecode
'For I = 2 To mECol.length - 1 Step +6
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
'Frm.Show()
Me.Invoke(New MethodInvoker(AddressOf Button__))
'Dim demoThread As System.Threading.Thread
End Sub
Private Sub CopyToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CopyToolStripMenuItem.Click, IDAndGameNameToolStripMenuItem.Click
Try
Dim s As String
Dim lsvrow
lsvrow = ListView1.SelectedItems(0)
s = "Game Name: " + lsvrow.Text + ControlChars.NewLine + "ID: " + TextBox2.Text
Clipboard.SetDataObject(s)
Catch ex As System.Exception
MessageBox.Show("Error: " + ex.Message)
Finally
' Perform any tidy up code.
End Try
End Sub
Private Sub CopyIDToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CopyIDToolStripMenuItem.Click, IDToolStripMenuItem.Click
Try
Dim s As String
Dim lsvrow
lsvrow = ListView1.SelectedItems(0)
s = TextBox2.Text
Clipboard.SetDataObject(s)
Catch ex As System.Exception
MessageBox.Show("Error: " + ex.Message)
Finally
' Perform any tidy up code.
End Try
End Sub
Private Sub ListView1_ItemActivate(sender As System.Object, e As System.Windows.Forms.ListViewItemSelectionChangedEventArgs) Handles ListView1.ItemSelectionChanged
TextBox2.Text = e.Item.SubItems(1).Text
End Sub
Private Sub TextBox1_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode = Keys.Enter Then
'Runs the Button1_Click Event
Button1_Click(Me, EventArgs.Empty)
End If
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click, ClearToolStripMenuItem.Click
ListView1.Items.Clear()
End Sub
Private Sub DownloadGPDToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles DownloadGPDToolStripMenuItem.Click, DownloadGPDToolStripMenuItem1.Click
Dim gpds As ArrayList = New ArrayList()
Const YOUR_DIRECTORY As String = "****"
' Get the object used to communicate with the server.
Dim request As FtpWebRequest = CType(WebRequest.Create(YOUR_DIRECTORY), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails
' This example assumes the FTP site uses anonymous logon.
request.Credentials = New NetworkCredential("****", "****")
Call wait(1500)
Dim response As FtpWebResponse = CType(request.GetResponse, FtpWebResponse)
Dim responseStream As Stream = response.GetResponseStream
Dim reader As StreamReader = New StreamReader(responseStream)
Dim s = reader.ReadToEnd
reader.Close()
response.Close()
If Len(TextBox2.Text) > 0 Then
If s.Contains(TextBox2.Text + ".gpd") Then
FolderBrowserDialog1.ShowDialog()
If Not FolderBrowserDialog1.SelectedPath = Nothing Then
Me.Text = "Game Finder | By Unh0ly | Downloading..."
Me.ToolStripStatusLabel1.Text = "Downloading..."
My.Computer.Network.DownloadFile("****" + TextBox2.Text + ".gpd", FolderBrowserDialog1.SelectedPath + "\" + TextBox2.Text + ".gpd", "", "", False, "100", True)
Me.ResetText()
Me.ToolStripStatusLabel1.Text = "Status.."
ElseIf FolderBrowserDialog1.SelectedPath = Nothing Then
Else
MessageBox.Show("No GPD for Selected Game")
End If
Else
MessageBox.Show("No GPD for Selected Game")
End If
Else
' Do Nothing
End If
End Sub
Private Sub ExitToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles ExitToolStripMenuItem.Click
Application.Exit()
End Sub
Private Sub CheckForUpdatesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CheckForUpdatesToolStripMenuItem.Click
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("****")
Dim response As System.Net.HttpWebResponse = request.GetResponse()
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(response.GetResponseStream())
Dim newestversion As String = sr.ReadToEnd()
Dim currentversion As String = Application.ProductVersion
Dim request1 As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("****")
Dim response1 As System.Net.HttpWebResponse = request1.GetResponse()
Dim sr1 As System.IO.StreamReader = New System.IO.StreamReader(response1.GetResponseStream())
Dim updurl As String = sr1.ReadToEnd()
If newestversion.Contains(currentversion) Then
MessageBox.Show("You have the current version", "Up to date", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
Dim result1 As DialogResult = MessageBox.Show("Newer version available" & vbCrLf & "Please Goto *** to check" + vbCrLf + "Do you want to go there now?", "Update Available", MessageBoxButtons.YesNo, MessageBoxIcon.Information)
If result1 = DialogResult.Yes Then
Process.Start(updurl)
Else
' Do Nothing
End If
End If
End Sub
Private Sub AboutToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles AboutToolStripMenuItem.Click
Dim gpds As ArrayList = New ArrayList()
Const YOUR_DIRECTORY As String = "****"
Dim request As FtpWebRequest = CType(WebRequest.Create(YOUR_DIRECTORY), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails
request.Credentials = New NetworkCredential("****", "****")
Call wait(100)
Dim response As FtpWebResponse = CType(request.GetResponse, FtpWebResponse)
Dim responseStream As Stream = response.GetResponseStream
Dim reader As StreamReader = New StreamReader(responseStream)
Dim s = reader.ReadToEnd
reader.Close()
response.Close()
Dim Lines() As String = s.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
MessageBox.Show("Made By Unh0ly aka Nickdudego3" & vbCrLf & "Number of GPD's: " & Lines.Length - 5 & vbCrLf & "Version: " & Application.ProductVersion, "About", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
End Sub
End Class
Here's a small sample how to use a worker..
Friend WithEvents myWorker As System.ComponentModel.BackgroundWorker
Me.myWorker = New System.ComponentModel.BackgroundWorker()
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
myWorker.RunWorkerAsync()
End Sub
Private Sub myWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles myWorker.DoWork
'do your stuff here...
End Sub
The best way to find bottle neck in your code is to put Timer.Start and Timer.Stop around your methods to find out which methods are taking the longest to excute.
Once you find the offending methods, you can use ThreadPool.QueueUserWorkItem to implement a basic background threading. Threading is by no means easy and it would take some time for you figure it out all the crazy and weird things that happen when you play with threads.
Hope this helps. If you have any more question, do ask.