Tutorial: Email sending with VB.Net


So you want to send email from your vb.net application? No problem!
A lot of times an email is sent in the “background” with pre-configured settings. These could be hard-coded, or stored in the Application/User Settings file. If you want to have fields in your WinForm that ask the user for the information, the concept will be the same, but with the additional step of validation, which is always a good thing 🙂

Let’s start with creating a new mail message:

Dim email As New MailMessage

This creates a new MailMessage object which we can then set the properties of before sending the email.
Next, we need to set the arguments for the Send method so that it is sent properly. We will need to properties for: From address, To address, Subject, and the body of the email.

From: Email address you want to appear at the recipient’s end and the name associated with the email address
Example – .From = New MailAddress(“jdoe@email.com”, “John Doe”)

To: Email address you want to send the email to and the name you want to appear (usually their full name)
Example – .To.Add(New MailAddress(“recipient@email.com”, “Jane Doe”))

Here, you will notice that there is an Add method which you can use to add multiple recipients to an email message. All you need to do is add another line like above for each recipient. If you had a list with email addresses, you could iterate through the list with a for loop adding the recipients one at a time:

.To.Add(New MailAddress("recipient1@email.com", "Jane Doe"))
.To.Add(New MailAddress("recipient2@email.com", "James Doe"))
.To.Add(New MailAddress("recipient3@email.com", "Jenny Doe"))

Subject: This is what will appear as the subject for the email (hard stuff huh?)
Example – .Subject = “I’m Sending Emails from my WinForm!”

Body: This is what will appear as the body, or message, of the email (it’s almost intuitive! /sarcasm)
Example – .Body = “Thanks to www.stateofidleness.com, I can send emails from my Windows app.”

So with these in mind, let’s code it in our application.
We can do this using a With structure:

With email
       .From = New MailAddress("jdoe@email.com", "John Doe")
       .To.Add(New MailAddress("recipient1@email.com", "Jane Doe"))
       .Subject = "I'm Sending Emails from my WinForm!"
       .Body = "Thanks to www.stateofidleness.com, I can send emails from my Windows app."
End With

Now the “hard” part. You will need to obtain your SMTP settings from your ISP or other email provider.

We’ll create a new SmtpClient which is required for sending the email

Dim mySMTP As New SmtpClient("smtp.server.address.com") 'You will put your SMTP server here

Now we need to put in our settings for Port, Credentials and whether we use SSL or not:

mySMTP.Port = 25 'Change to whatever port your SMTP server uses
mySMTP.EnableSsl = False 'True or False depending on your SMTP server
mySMTP.Credentials = New System.Net.NetworkCredential("me@test", "password") 'Enter your username and password you use when sending email

These are the settings that would be most likely kept in a config file and not hard-coded, as a server address may change, or a username and password will most likely change. You don’t want to have to recompile every time your password changes.

We’re almost done! All we have to do now is send the thing! To do this, we call the Send method and pass it our email object:

mySMTP.Send(email)

That’s it! Now let’s look at the code all together:

Dim email As New MailMessage
With email
       .From = New MailAddress("jdoe@email.com", "John Doe")
       .To.Add(New MailAddress("recipient1@email.com", "Jane Doe"))
       .Subject = "I'm Sending Emails from my WinForm!"
       .Body = "Thanks to www.stateofidleness.com, I can send emails from my Windows app."
End With

Dim mySMTP As New SmtpClient("smtp.server.address.com") 'You will put your SMTP server here
mySMTP.Port = 25 'Change to whatever port your SMTP server uses
mySMTP.EnableSsl = False 'True or False depending on your SMTP server
mySMTP.Credentials = New System.Net.NetworkCredential("me@test", "password") 'Enter your username and password you use when sending email
mySMTP.Send(email) 'Bon Voyage!

And off it goes! That’s all there is to it. Hopefully this tutorial helps you in sending emails from your VB.Net apps.

Share Links?

If you’re a blogger and in the design/developing field of expertise, I’d love to trade links with you. Not only will this help increase traffic, but will act as a pseudo electronic rolodex for useful sites and inspiration! Just leave your link in the comment and a graphic you’d like to use if you have one.

Here’s mine:

Code to use:


<a href="http://stateofidleness.com">
<img src="http://stateofidleness.com/images/header.png" />
</a>

Tutorial: Autofill HP Service Manager (HPSM)


So I’ve been asked by a couple of people how I managed to autofill a new HP Service Manager Service Ticket. This is what my company uses for service ticket handling and what not. The IRIS program is able to auto-submit tickets when a device fails a certain amount of times. Here’s the code!

Public Class serviceTicketForm
    Dim numFramesLoaded As Integer = 0
    Dim storeName As String = &quot;&quot;
    Dim newLocation As String = &quot;&quot;
    Dim description As String = &quot;&quot;

    Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If My.Settings.certServer = CheckState.Checked Then
            'Certification environment
            wb2.Navigate(&quot;&lt;a href=&quot;https://certificationserver:port/webtier-7.01/ess.do&quot;&gt;https://certificationserver&lt;/a&gt;&quot;)
        Else
            'Production environment
            wb2.Navigate(&quot;&lt;a href=&quot;https://productionserver:port/webtier-7.01/ess.do&quot;&gt;https://productionserver&lt;/a&gt;&quot;)
        End If

        numFramesLoaded = 0

        'Set window location to bottom right corner
        'Me.Top = (frmMain.Top + frmMain.Height) - (Me.Height + 15)
        'Me.Left = (frmMain.Left + frmMain.Width) - (Me.Width + 15)
    End Sub

    Private Sub autoLogin()
        Dim username As String = My.Settings.TicketUsername
        Dim password As String = My.Settings.TicketPassword
        Try
            'Username (Default is Windows Credentials)
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X2&quot;).SetAttribute(&quot;Value&quot;, username)
            'Password
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X5&quot;).SetAttribute(&quot;Value&quot;, password)
            '&quot;Click&quot; the button
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X8&quot;).InvokeMember(&quot;click&quot;)
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub fillForm()
        Dim methodOfContact As String = &quot;Email&quot;  'Sets the method of contact to &quot;Email&quot; so that I get an email response back when the ticket is closed

        Try
            'Preferred Method of Contact
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X8&quot;).SetAttribute(&quot;Value&quot;, methodOfContact)

            'Location needing service
            getLocationFromIP() 'Calculates the location name based on the Device name. This is custom to my use, so it will vary for yours
            'You could also just set newLocation equal to a known value of the drop down box
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X24&quot;).SetAttribute(&quot;Value&quot;, newLocation)
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X24&quot;).Focus()
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X24&quot;).InvokeMember(&quot;onkeyup&quot;) 'This forces the dropdown box to do the lookup and register the change

            'Description of the service being requested
            getDescription()
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X29&quot;).SetAttribute(&quot;Value&quot;, description) 'This fills in the description of the needed service

            'Submit the thing!
            wb2.Document.Window.Frames(1).Document.GetElementById(&quot;X31&quot;).InvokeMember(&quot;click&quot;) 'Clicks the submit button!

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub getLocationFromIP()
        Dim ip As String = frmMain.recordersOfflineLV.Items(frmMain.recordersOfflineLV.Items.Count - 1).SubItems(1).Text
        Dim corp1 As String = &quot;&quot;
        Dim corp2 As String = &quot;&quot;
        Dim corp3 As String = &quot;&quot;

        corp1 = ip.Substring(6, 1)
        corp2 = ip.Substring(9, 1)
        corp3 = ip.Substring(10, 1)
        newLocation = &quot;00&quot;
        newLocation = String.Concat(corp1, corp2, corp3)
    End Sub

    Private Sub getDescription()

        description = &quot;This is where your service ticket text goes. The description of the service needed. etc..&quot;

    End Sub

    Private Sub waitThenClose_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles waitThenClose.Tick
        If My.Settings.certServer = CheckState.Checked Then
            'Certification Environment
            wb2.Navigate(&quot;&lt;a href=&quot;https://certificationserver:8443/webtier-7.01/cwc/goodbye.jsp&quot;&gt;https://certificationserver/cwc/goodbye.jsp&lt;/a&gt;&quot;)
        Else
            'Production Environment
            wb2.Navigate(&quot;&lt;a href=&quot;https://productionserver:8443/webtier-7.01/cwc/goodbye.jsp&quot;&gt;https://productionserver/webtier-7.01/cwc/goodbye.jsp&lt;/a&gt;&quot;)
        End If
        transForm.Close()
        Me.Close()
    End Sub

    Private Sub wb2_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles wb2.DocumentCompleted
        numFramesLoaded += 1
        Select Case numFramesLoaded 'Counts the frames that have loaded so that I know which page it is currently on.
            Case 8 'Tells me it is the Login Page
                'Login page
                statusLabelTicket.Text = Environment.NewLine  &quot;Logging in...&quot;
                autoLogin()
            Case 10 'Tells me it is the Form Page
                'Service page
                fillForm()
                statusLabelTicket.Text = Environment.NewLine  &quot;Processing...&quot;
            Case 11 'Tells me it is ready for Log Out Page.
                'Logout cleanly
                If My.Settings.certServer = CheckState.Checked Then
                    'Certification Environment
                    wb2.Navigate(&quot;&lt;a href=&quot;https://certificationserver:8443/webtier-7.01/cwc/logoutcleanup.jsp&quot;&gt;https://certificationserver/cwc/logoutcleanup.jsp&lt;/a&gt;&quot;)
                Else
                    'Production Environment
                    wb2.Navigate(&quot;&lt;a href=&quot;https://productionserver:8443/webtier-7.01/cwc/logoutcleanup.jsp&quot;&gt;https://productionserver/webtier-7.01/cwc/logoutcleanup.jsp&lt;/a&gt;&quot;)
                End If
                statusLabelTicket.Text = Environment.NewLine  &quot;Submitted!&quot;  Environment.NewLine  &quot;Logging out...&quot;
            Case 13 'Tells me it logged out cleanly
                waitThenClose.Start()
        End Select
    End Sub
End Class

Things you will need to check: You can see that I have a cert server and a production server available. I have a checkbox on my main form that lets me toggle between the two, for testing. I don’t want to send fake tickets to the Service Desk team.. They tend to hate me when I do that 🙂

Also, ‘statusLabelTicket’ is a label that basically states what the current progress is on the form.

The getLocationFromIP() procedure basically converts the device’s IP address into a Store Location. This will not be applicable to most people and will need to be edited or deleted where necessary.

Have fun!

Comments welcome.

Tutorial: Ping Network Device


Introduction: I often see many people asking how to do a ‘ping’ in VB.NET. It is actually quite simple and I utilize it in my IRIS project. This tutorial will teach you how to ping a network device and view the pings’ results.

What you will need: Any version of Visual Studio (Express is fine), a few free minutes and your energy drink of choice.

First, what does it mean to “ping?” A ping is useful when you need to know if a network device is communicating with other network devices. This could be a computer, phone, IP Camera, or pretty much anything that has networking capabilities and an IP address.

Author Note: A Ping may not always provide a good indication if a device is communicating or not. Many System Administrators will disable ICMP messages to “hide” a machine on the network from malicious entities.

Let’s start by opening a new project and adding a blank Windows form. We will add a Textbox, a Button and a Label control to the form like so:

Ping Form Layout

We will name the controls:

ipTextbox
resultLabel
pingButton

What we are going to do is have the user enter an IP address (format xxx.xxx.xxx.xxx) into the Textbox and clicking the button will ping the IP. The results of the ping ("Online" or "Offline") will then show in the label.

Let’s double-click the pingButton to create and enter its Click Event code block. We are going to call a function, IsDestinationReachable, which will accept the IP (provided from ipTextbox) as a string argument. (We will code this function later in the tutorial) This function will return reachable, a boolean value that tells us True (Online) or False (Offline). We are going to test the value of reachable and if it is True, set the Label’s Text property to "Online," and if it is False, set it to "Offline." So our code will be:

    Private Sub pingButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles pingButton.Click
        If IsDestinationReachable(ipTextbox.Text) Then
            resultLabel.Text = &amp;amp;amp;amp;amp;amp;amp;amp;quot;Online&amp;amp;amp;amp;amp;amp;amp;amp;quot;
        Else
            resultLabel.Text = &amp;amp;amp;amp;amp;amp;amp;amp;quot;Offline&amp;amp;amp;amp;amp;amp;amp;amp;quot;
        End If
    End Sub

Now that we have our button coded, let’s work on that function. We’ll begin by declaring it a Private function and naming it. It will accept the string By Value and store it in hostnameOrAddress. We will declare our reachable boolean variable and initialize it to False.

Now we will enter what’s called a Try/Catch block. This will alert us if any exceptions (errors) show up when the ping is taking place. We are going to use the Network class to send and receive status information.

My.Computer.Network.IsAvailable
My.Computer.Network.Ping('ip, 'timeout)

Here is the IsDestinationReachable function:

    Private Function IsDestinationReachable(ByVal hostnameOrAddress As String) As Boolean
        Dim reachable As Boolean = False
        Try
            reachable = My.Computer.Network.IsAvailable AndAlso _
                        My.Computer.Network.Ping(hostnameOrAddress, 10000)
        Catch pingException As System.Net.NetworkInformation.PingException
        Catch genericNetworkException As System.Net.NetworkInformation.NetworkInformationException
            ' Fail silently and return false
        End Try
        Return reachable
    End Function

We start by declaring it a Private function and naming it. The reachable boolean gets declared and initialized and then we enter our Try/Catch block. We then use the Ping method of the Network class by sending it our IP (provided from ipTextbox.Text) and a timeout amount, which I’ve made 10000ms above. The result of this ping gets stored in the reachable variable, either True or False. When we return back to the method call in the button’s click event, we test the value of reachable. If the result was True, we set our Label’s text to “Online”, if the result was False, we set the text to “Offline.”

At this point, you should be able to compile and run your program without any errors. (cross your fingers :))

Let’s start by entering a known good IP address. We’ll use 127.0.0.1 (Localhost, which will return Online). When you enter this into the Textbox and click the button, after a second or two, the Label will display “Online.”

Ping Success

So far so good!

Ok, now let’s try a bad IP address. We’ll use 100.100.100.256 (the last octet is outside the 255 range so will return Offline). Go ahead and enter this IP and click your button and see what your Label says now. If all went correct, you should see the screen below:

Ping fail

Let’s take a look at the code all together now:

Public Class mainForm

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Nothing to do here
    End Sub

    Private Sub pingButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles pingButton.Click
        If IsDestinationReachable(ipTextbox.Text) Then
            resultLabel.Text = &amp;amp;quot;Online&amp;amp;quot;
        Else
            resultLabel.Text = &amp;amp;quot;Offline&amp;amp;quot;
        End If
    End Sub

    Private Function IsDestinationReachable(ByVal hostnameOrAddress As String) As Boolean
        Dim reachable As Boolean = False
        Try
            reachable = My.Computer.Network.IsAvailable AndAlso _
                        My.Computer.Network.Ping(hostnameOrAddress, 10000)
        Catch pingException As System.Net.NetworkInformation.PingException
        Catch genericNetworkException As System.Net.NetworkInformation.NetworkInformationException
            ' Fail silently and return false
        End Try
        Return reachable
    End Function

End Class

That wasn’t so bad now was it? You can use this ping functionality a number of different ways. You can have the user supply the IP address, you can hard code it, you can load it from a text file or a database, the list goes on! See what you can come up with and report back!

As always, let me know if you found the post helpful. Comments, good or bad (but I like the good ones :)) are welcome!

IRIS Background

Ok, so in the race to compete with the highly-paid “solutions provider” my company has hired… actually let me precede that sentence with some history… Company I work for has hired a software developer to develop a set of applications that are aimed to integrate with our DVR vendor’s hardware. These applications include a Status monitoring tool for determining the DVR’s online and offline status, a configuration/playback application for reviewing footage and another small app that interfaces with our alarm monitoring software to provide video footage on alarms.

I probably can’t go into too much detail with the who’s and what’s for privacy reasons. I love my employer and don’t aim to jeopardize my position or theirs.. so.. with that said, I have always had a “if you want something done right, do it yourself” attitude and it has reared its ugly head once again. With weeks, sometimes months between “releases” of these apps from the software provider, it became a bottleneck not only for my productivity, but my patience 🙂

It started with the Status monitoring tool. From the onset, I had thought to myself, “I know I could make that a little more user-friendly,” or “It could be tailored so much more”.. mind you, these are highly customized applications strictly for our company (a large retailer) so my expectations were high. Also, with a background in computer programming and a love for technology in general, I was always tasked with “beta testing” for the company or “providing feedback” for upgrades or “things to do.”

Well I finally decided, I was going to try to make my own set of tools that I could use with these 3(really 4) goals in mind:

  • They had to make me more productive and efficient
  • They had to outperform and “one up” the purchased applications (otherwise, what’s the point right? 🙂 )
  • They had to be “universalized” so that they were not so tailored in architecture
  • I also wanted to try to integrate all the apps into one full-blown app for convenience sake. I’m a fan of consolidation.

So I went to work.

IRIS was born. Integrated Remote Infrastructure Suite.

IRIS

First Post!
I’ll be updating this with details from my IRIS project that I’m working on. In short, IRIS is a network device monitor I’m creating in VB.NET. The goal is to be able to monitor network device’s online or offline status utilizing a simple ‘ping’. This tool will be useful for IS or other System Administrators that occasionally find the need to see if a server is down. I will be uploading the source code shortly. I am in need of help to convert the existing, working, project to a multi-threaded application to facilitate scanning multiple groups of devices at one time and also separating the ‘leg work’ from the UI for better user experience.

Overview:
I’m using Visual Studio 2005 Express and an Access database with a Table for each Device group. I have 3 groups: Device1, Device2, Device3. Each Table has a field for Device Name, IP address, and Notes that are used to populate a “Details” ListView for each Device Group. Each ListView has controls to “Start a Scan”, record online and offline Devices in separate ComboBoxes.

The main form consists of 3 tabs: Options, Devices and Device Data. The Options tab is used for display settings, email and taskbar notifications, file output enable/disable, font and color settings etc. The Devices tab is where the Device groups are loaded into 3 separate ListViews. This is where the actual scan takes place by iterating through the lists 1 Item at a time and pinging it for a response. The Device Data tab consists of 3 DataGridViews used for editing the tables in the database for the corresponding device group.

A scan will iterate through the ListView one item at a time. It pings the device, and sets the Items Forecolor to Green or Red depending on the the response (Up or Down).

At the end of every scan, a text file with the Offline devices, the Online count and the Offline count and uploads it our company’s Intranet Sharepoint site into a Document Library. Then, a Flash file displayed on one of the Sharepoint pages displays the contents of the text file. This makes the results available to everyone so that only one copy of the program needs to be ran. The completion of a scan also sends an email with the same contents of the text file. The email settings are configurable.

Current Status:
Currently, the program works fine! I have all ListViews populating at runtime for each device group. I also have “import” functions to load the device table data into its own DataGridView on the Device Data tab. Scanning works correctly for a list as it iterates through one item at a time, and based on an “accuracy” setting, will ping the device that many times before declaring an offline or online status.

Where I’m Struggling:
I need help converting the current code into multi-thread-friendly code to allow the scanning of multiple device groups simultaneously and allowing for form interaction while a scan is taking place. As it stands now, I am only able to scan one list at a time, and if a lot of devices in a row are down, the Interface will become “frozen” to the user. I want to separate this scanning code from the interface.

Because I have created the program to about 80% completion already, and most of it using the “drag-and-drop” method of adding controls, I am encountering MANY “cross-thread” errors in my attempts to implement threading.

Planned Additions:

  • Recording time device is seen as offline (included in email and web stats)
  • Recording length of completed scan
  • Recording number of successful scans (within the program)
  • Recording number of times device is seen as offline (ie: 5 Failed Attempts)
  • Ability to import from spreadsheet
  • Audible alarms for all device types (currently I only have audio notifications for Device 1)
  • Application-level access prevents devices from being known until logged in
  • Several options for sorting, viewing select devices, colors, font sizes
  • Output to Excel spreadsheet
  • An option to “Import Devices” from a Spreadsheet into the 3 ListViews

In Closing:
I think this will be a valuable tool for many people when completed. I’d like to make it open source, but not sure how all that works (providing source, files, etc. if someone with experience with this could help me out, that’d be great). I would really love to get some very knowledgeable VB and .NET programmers’ input and feedback on this application. Also, at some point, I’d like to “port” this to ASP.NET to run completely via web browser.

I appreciate you taking the time to read all that! If you’re interested in helping or want to send a friendly suggestion or comment, please don’t hesitate!