Archive for May, 2007

A Look at When to Rewrite Your VB6 apps in VB.NET

Has your app become this toxic?A common question is, “When should I update a working, deployed, VB6 app to VB.NET?” The answer, in part, depends on how well the VB6 app is doing its job and if it is showing warning signs that indicate that it is nearing the end of its lifecycle. In this article, I’ll cover some of these warning signs.

First of all, don’t upgrade simply for the sake of upgrading. If the app is doing its job and working well there is no need to change it until outside factors require it. For example, one doctor I went to 2001 was using a custom DOS program written in Clipper that he had commissioned in the late 1980’s! It worked for his practice and he saw no need to change until regulation changes force him to do so. But, what if your application isn’t such a smooth operation?

Many VB6 programs, over time, get what I call the Winchester House effect. In case you didn’t know, the Winchester House was built by the widow of inventor of the Winchester rifle. To avoid hauntings a medium told her about, she kept the house under construction for 38 years and this resulted in a sprawling mansion that had many features that made no sense. Like this house, many VB6 programs have been added to and added to over the years until they become monsters with 100’s of forms and modules, some of which no longer make any sense.

When a program gets in this state you’ll begin to see “fatal improvements”. That’s what happens when a small change in one part of the program causes failures in other parts of the program. If a single line of code is changed and this causes indeterminable erratic behavior by the program, you’ve got a problem with that program. If you find yourself telling other programmers to avoid making changes in troublesome modules, this is a warning sign that your application’s quality is degrading.

Another sure sign of program quality degradation happens when new developers are brought onto your team or when you have to discuss the program with people outside your team. If you have to describe a myriad of special conditions and circumstances that a newcomer must be careful about, this is a sign of impending disaster. If you find that you can’t adequately and concisely describe what the program is supposed to do in certain modules to an outsider, that’s a problem. If you find that you can’t give a tester or a code reviewer the information they need to adequately do their job, this is yet another of impending failure.

Another sign of trouble is if you can’t rollback your releases easily. If the program has become so complex that returning to a previous release is just as troublesome as deploying a new release, that’s means it’s time for a change. Even worse, if no one really knows how to get back to the previous production release, this is a very serious problem.

So, if you see the quality of your VB6 application degrading in this way, it is prime time for undertaking a redesign using VB.NET. In later articles, I’ll cover some techniques for extracting a VB6 program’s design and ways to implement a gradual update if your program isn’t already on its last legs.

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

Add comment May 29th, 2007

Encourage Creativity

A business has to be involving, it has to be fun, and it has to exercise your creative instincts. - Richard BransonThe number one benefit of information technology is that it empowers people to do what they want to do. It lets people be creative. It lets people be productive. It lets people learn things they didn’t think they could learn before, and so in a sense it is all about potential. - Steve Ballmer

Software development is often seen as a purely analytical, linear, “left brain”, exercise. Many organizations manage software development projects this way and have a culture that rejects creativity by individual developers. However, many development projects also require a lot of “right brain”, fuzzy, non-linear, thinking to be their best or, in some cases, successful at all.

One thing I’ve noted about some of the best programmers I’ve worked with is that they also have some kind of artistic outside interest. My own guitar playing would be one example. I’ve worked with several excellent programmers who were also musicians. Others were painters, some were furniture makers, one even wrote novels and short stories. I suspect you’ll find a lot of “frustrated artists” in many IT organizations.

First, let’s not mistake creativity for general hacking a program together without a cohesive plan. To use a musical perspective, when playing in a group jam session everybody needs to know what key they’re playing in and at what tempo, when to take the lead and when to play rhythm, and so forth. In programming, this compares to tools, requirements and design specs that everyone agrees to use. Creativity isn’t simple chaos but the organization of thoughts that transform random bits of information into a useful whole.

Creativity isn’t just a coding thing. It can be used during the requirements gathering and design phase too. Creative “out of the box” collaborative thinking at this phase can greatly improve a project’s outcome. Handing developers a fixed spec and schedule that nips creativity in the bud will ultimately produce a weaker end product. You’ll get a Velvet Elvis rather than a Mona Lisa.

Many managers are concerned that if they allow creativity that the process will fall by the wayside. The overall development process is important, but it also has to support creative thinking. The goal is to make sure that the people on your team see that the process that’s implemented supports their creativity and doesn’t stifle it. Excessive time tracking, ‘TPS’ reports, required staff and company meetings and other such things can be creativity killers. Managers should use their own creative skills to eliminate useless tasks and to keep processes that insure not just a good, but a great, final product.

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

Add comment May 28th, 2007

System.Net.Mail How To

You've Got System.Net.Mail!VS 2005 / Framework 2.0 adds a new way to email, the System.Net.Mail Namespace that uses SMTP (Simple Mail Transfer Protocol) to deliver messages. In this article, I’ll provide a simple example of how to use it and go over a couple of quirks that people get hung up on.

The MailMessage and SmtpClient classes are the heart of this new Namespace and sending an email is really just a matter of a couple of lines.
.
.
.
.
.

Dim EmailServer As New System.Net.Mail.SmtpClient(EmailServerName)
EmailServer.SendAsync(TestEmail, Me)

The code above makes a couple of assumptions. First, that the variables for the call have been filled with correct information and, second, that the target SMTP server uses Windows authentication. Also note that the MailMessage class implements the IDisposible interface so you might think it’s a candidate for the Using block as I mentioned in a previous article. However, since it is called async, the Using block would dispose of it prematurely so this is an exception to the rule where you should not use Using.

In addition to the basics of From, To, Subject, Body, you can use properties of the MailMessage to add attachments, set the CC and BCC, select the encoding method for the body, and do a few other things. For example, if you wanted to add a CC to the message above the code would look like this:

Dim TestEmail As New System.Net.Mail.MailMessage(EmailFrom, EmailTo, EmailSubject, EmailBody)
TestEmail.CC = EmailCC
Dim EmailServer As New System.Net.Mail.SmtpClient(EmailServerName)
EmailServer.SendAsync(TestEmail, Me)

If you wanted to add an attachment to the email, the code would look like this:

Dim TestEmail As New System.Net.Mail.MailMessage(EmailFrom, EmailTo, EmailSubject, EmailBody)
TestEmail.CC = EmailCC
TestEmail.Attachments.Add(New System.Net.Mail.Attachment(EmailAttachmentFileName))
Dim EmailServer As New System.Net.Mail.SmtpClient(EmailServerName)
EmailServer.SendAsync(TestEmail, Me)

There are several overloads available for creating attachments so you may want to consult MSDN help if you need more advanced options.

In the demo program, I keep it simple without CC’s or attachments although I do add in a callback for the async operation. Using the callback allows you to verify that the email was sent or not sent without tying up your program waiting for a response.

What if you need to authenticate onto a remote SMTP server where you don’t have Windows authentication available? In this case, you’ll need to create credentials, like so:

Dim TestEmail As New System.Net.Mail.MailMessage(EmailFrom, EmailTo, EmailSubject, EmailBody)
TestEmail.CC = EmailCC
TestEmail.Attachments.Add(New System.Net.Mail.Attachment(EmailAttachmentFileName))
Dim EmailServer As New System.Net.Mail.SmtpClient(EmailServerName)
EmailServer.Credentials = New System.Net.NetworkCredential("emailaccount@remoteserver.com", "mypassword", "mail.remoteserver.com")
EmailServer.SendAsync(TestEmail, Me)

In most cases you will need to provide the domain name on the email account ID and you’ll need to confirm that the mail subdomain is correct and allows this kind of login. Your password is sent as clear text basic authentication in this scenario so be careful! You can use other options to provide a more secure connection if your SMTP server supports them.

Now for a couple of quirks with System.Net.Mail.

First, if you’ve used other and earlier mail engines you may have gotten used to separating multiple TO email addresses with a semi-colon, like so:

EmailTo = "mrblah@mydomain.com; msblank@mydomain.com"

However, in this case a formatting exception will be thrown. Yes, it surprised me too the first time this happened. The correct delimiter to use with System.Net.Mail is a comma, like so:

EmailTo = "mrblah@mydomain.com, msblank@mydomain.com"

My other quirk that you might encounter is that the low level code that System.Net.Mail uses might get mistaken for a mass emailing virus by some versions of anti-virus software. While these anti-virus block System.Net.Mail email they will allow email by older CDO and System.Web.Mail methods to function normally. If you encounter this problem, the solution is the consult with the anti-virus company to see if they have an update available or you might want to risk disabling this part of the anti-virus protection, depending on your circumstances. As a last resort, you can fall back to the older methods that should work OK.

» Click here to download VB.NET source code for this article.

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

10 comments May 27th, 2007

Beware of the Byte Order Mark

Beware! This dog will byteVS 2005 includes several new file management wrappers in the My.Computer.FileSystem namespace, including WriteAllText. This method is a quick and handy way to write small sized strings to disk but this method has a ‘gotcha’ in it. It uses UTF-8 encoding with a Byte Order Mark by default. This mark can easily confuse programs that aren’t expecting it.

What is a Byte Order Mark? Simply put, it’s a set of characters at the beginning of a Unicode text file that denote how the file is encoded. For UTF-8, the characters are the byte sequence EF BB BF, which appears as the characters “”.

Many Windows programs and .NET functions handle this transparently for you so you never see these characters. For example, if you open a UTF-8 encoded file in Notepad, you won’t see these characters at all. This ‘helpfulness’ can make it difficult to spot a that the encoding of the file is a problem.

How can it be a problem? The problems come up when a program that expects ASCII encoding tries to read the file. For example, you might be sending files you create to a third party program. It loads the file and sees the Byte Order Mark and assumes that the file isn’t in the correct format and rejects it. If you load the file into Notepad it looks OK to you but the target program can’t read it. It can be a frustrating problem to track down.

WriteAllText is different from similar methods, System.IO.StreamWriter and System.IO.File.WriteAllText. They do write UTF-8 encoding by default but they do not include the Byte Order Mark. So, if you were using StreamWriter in VS 2002/2003 or used System.IO.File.WriteAllText elsewhere and switched to My.Computer.FileSystem.WriteAllText there is a difference in the output files you’re producing.

So, to avoid this kind of problem, use the overload for My.Computer.FileSystem.WriteAllText that includes encoding and avoid the one that doesn’t. In fact, my recommendation is to always specify the right encoding method no matter which method you use.

Use:

My.Computer.FileSystem.WriteAllText(MyFilename, MyString, False, System.Text.Encoding.ASCII)

System.IO.File.WriteAllText(MyFilename, MyString, False, System.Text.Encoding.ASCII)

Using sw As New StreamWriter(MyFilename, False, System.Text.Encoding.ASCII)
    'writing code here
End Using

OK (but not recommended):

System.IO.File.WriteAllText(MyFilename, MyString, False)

Using sw As New StreamWriter(MyFilename, False)
    'writing code here
End Using

Avoid:

My.Computer.FileSystem.WriteAllText(MyFilename, MyString, False)
Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

4 comments May 26th, 2007

Using Binary Serialization

Scotty, beam up my objects.Binary Serialization is the process of storing the state of an object in a binary stream. The public and private members of the object as well as the name of the class are converted to a stream of bytes. This data can be written to disk, transmitted, or other managed in other ways that are applicable to data streams. When the object is deserialized, an exact clone of the original object is created. Think of it as a Star Trek style transporter for your objects.

This simple example shows how to save and restore the contents of a listbox using Binary Serialization. In the application, the program reads the listbox data from disk, if it exists, then the user enters new items into the listbox. They may also clear one, many, or all of the items from the list and save the data if they wish. Finally, when the program is closed the user has the option to save the data to disk again. Let’s look at some of the details.

First, we have to setup our references right to use Binary Serialization. We will need use the following:

Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary

They should be loaded as the default references but you will need to import them or type quite a long line of code to reference them.

Next, in the Form’s load routine we see how to use the BinaryFormatter:

Using fs As New IO.FileStream(_dataFile, IO.FileMode.Open, IO.FileAccess.Read)
    lstItems.Items.AddRange(DirectCast(New BinaryFormatter().Deserialize(fs), Object()))
End Using

Note that we put the FileStream in a Using block to insure that it releases the file after it reads in the data. See my article on Using for more details on this. In the block we use the AddRange method of the Listbox’s Items collection to load the deserialized Object array contents into the listbox.

Why did we need to use an Object array rather than the Listbox’s built-in ObjectCollection? The reason for this is that the ObjectCollection is not serializable. In order for an object to be serialized it needs to be built that way and the ObjectCollection nor the Listbox itself are serializable. So, we will need to convert the items to and from Object arrays in this case. In your own classes you want to serialize, use the Serializable attribute to mark it this way, as in this example:

<Serializable()> _
Public Class MyClass

Also, we use DirectCast insure that .NET knows exactly what kind of object we’re expecting to be loaded.

Now, when we’re prepared to save the listbox data, we reverse the process. Once again we use the Using block for FileStream operations.

Using fs As New FileStream(_dataFile, IO.FileMode.Create)
     Dim items(lstItems.Items.Count - 1) As Object
     lstItems.Items.CopyTo(items, 0)
     Dim bf As New BinaryFormatter
     bf.Serialize(fs, items)
     fs.Close()
End Using

Next, we will need to copy the ListBox’s items from its ObjectCollection to an object array in order to serialize it. We do this by using the CopyTo method. Next the array is serialized to the FileStream and we’re done.

Binary serialization is a effective tool to use when you need to persist data without a using a database or when you want to transfer data from one location to another. Web Services often use it or its cousins XML and SOAP serialization to transfer data. It’s a great tool to add to your VB.NET bag of tricks.


» Click here to download VB.NET source code for this article.

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

Add comment May 25th, 2007

Previous Posts


Visit Me At My New Site, Programming In C#

Most Popular Articles

Highest Rated Articles

Categories

Most Recent Articles

Feeds

 Subscribe in a reader

To subscribe by e-mail
Enter your address here

Delivered by FeedBurner

VB Opportunities

Archives