
August 2, 2008
How to Write a Windows Service
Writing a windows service is actually not much different than
writing any other piece of .Net code. There are a few differences, however, that
should be noted.
Setting up a Windows Service
As with any Visual Studio Project, you select new project from the file
menu. Then select the language you are programming in (c# for example) and the
windows submenu. From there you can select "Windows Service." You'll notice that
you get just a blank page in designer view because there is really nothing to
design. There is no gui interface! So you have to switch to code view to do
anything.
Coding a Windows Service
In code view you can code your service just as you would code anything else.
However, there are a few additional things you may want to consider. By default,
there is an OnStart and OnStop method. These are called when you start the
service or when you stop the service. I always put some event log functionality
in these methods.
For example within the Service class, add the method:
protected override void OnStart(string[] args)
{
EventLogger.LogMessage("Starting Doug Service", "myService", 1000);
}
I usually add this part in a separate class within my project:
using System.Diagnostics;
public class EventLogger
{
private EventLogger()
{
}
public static void LogMessage(string message, string source,
int messageCode)
{
EventLog log = new EventLog("Application",
System.Environment.MachineName,
source);
log.WriteEntry(message,
System.Diagnostics.EventLogEntryType.Information,
messageCode);
log.Close();
}
}
I usually put the EventLogger in a separate project and call it as I need it. You can create separate methods for warnings and errors and just change the System.Diagnostics.EventLogEntryType as appropriate.
Installation
The installation of a windows service in .Net 3.5 is actually quite different.
First, you cannot test a windows service in debug mode in Visual Studio. You
actually have to install the service to test it. There are a couple of important
steps to this installation.
First, right click on the name of your project in solution explorer and select Add...New Item. A window should pop up asking what you want to add. From the General submenu, select Installer class. This should add an installer class to your project and bring up the Designer page for the installer class. The designer page should be empty at the moment, but we are going to add a couple of things to it.
First, we need to add a service installer to your
toolbox. From the menu at the top of VisualStudio, select Tools and then Choose
Toolbox Items. Another window should pop up. Scroll down to
"ServiceInstaller" and "ServiceProcessInstaller". Check both of those boxes and
hit ok. They should then be added to your toolbox.
From your toolbox, drag a ServiceProcessInstaller and a ServiceInstaller over to the design page of your Installer class.
ServiceInstaller Properties
Click on the serviceInstaller item on the design page of your installer class
and select the properties. The two most important properties here are the Parent
property and the ServiceName property. Change the Parent property to the name of
your Installer Class. By default, when you added the installer class, the name
was Installer1, but if you changed the name of your installer, you need to
change it here. You will also set the name of the service here in ServiceName.
When you pull up windows services after it is installed, this will be the name
of the service that you see. The start type can be Manual, which means that you
must manually start the service after it has been started. It cannot be started
from an application that calls it. Automatic means that the service will start
automatically when it is called from an application.
ServiceProcessInstaller Properties
The two most important properties here are the account property and the
Parent property. Set the parent property equal to the name of the
ServiceInstaller from the previous step. The account property can be set to
User, Local System, Network Service, and Local Service. This determines the
authority that the service has to open files, access the network, etc...By
default the service is set to User authority, but if your system is going to be
handling admin type processes, you will need to set it to Local System. You can
view information about the different service accounts here:
http://msdn.microsoft.com/en-us/library/ms686005(VS.85).aspx
Actual Installation
Once you have written the code for your service and added the appropriate
installation code, you are ready to install your service. Navigate to the debug
folder of your project (where the compiled .dll files are) from a command line.
If I am just debugging the service on my local machine, I usually just install
and uninstall the service from my debug folder. To install the service, you will
use a utility provided by Microsoft called InstallUtil.exe. From the command
line, just type: installutil <name of service>. To uninstall the service type:
installutil -u <name of service>. You can find a lot more information about the
installer tool here:
http://msdn.microsoft.com/en-us/library/50614e95(VS.80).aspx
Conclusion
Windows services can be especially handy when you want to monitor something
going on on your system. For example, you may want to monitor the space on a
backup drive or the changes made to a system folder. You can also setup a
service to listen in on tcp ports or respond to specific application requests.
Testing and debugging can be a little tricky, though, because you actually have
to install the service to test it. It can be even trickier if you are trying to
install and test the service from a remote machine. But the installutil.exe
utility is very easy to use.
May 25, 2008
Contact Me Page
I wanted to write a bit about the contact me page. You can click on the link at
the top of this page to reach another page with a form to contact me. The form
uses asp.net tags and a vb code-behind with some pre-built .net functionality to
edit check the form entries.
First and Last Name
The first two entries on the page are first name and last name. The entry fields
use two .net validation controls:
RequiredFieldValidator - this control checks to make sure that something is entered on the form (i.e., it is not null) when the submit button is pressed.
RegularExpressionValidator. The one I used is as follows:
^[a-zA-Z]+((\s|\-)[a-zA-Z]+)?$
It makes sure that valid characters are entered. I updated it recently to accept
one space OR one dash in case the person has a two part name.
E-mail
Again, I used the RequiredFieldValidator and the RegularExpressionValidator.
Here is the regular expression:
\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
I didn't write that one, by the way. Microsoft
recommends that as the regex for "internet e-mail"
Here is the full asp entry for the email regex validator:

Retype E-mail Address
Like many websites nowadays, I ask you to retype your e-mail address, just to
make sure you didn't mistype something. .Net ships with a CompareValidator that
makes sure the two entries match. All you have to do is tell it what to compare
to. Easy. easy. easy.
Subject
For the subject, I just make sure you have one.
Message
There is no validation on the message.
Why all the hassle?
There are several reasons to go through all There are several reasons to go through all this validation hassle:
Hackers love to mess around with sites that accept user input but don't do any validation. They are really easy targets. I don't profess to be any sort of hacker, but I do know that user input can, in certain situations create an entry point for the resourceful hacker. Validation makes it more difficult.
People make mistakes. Even when I type my e-mail address, I sometimes mistype it without paying attention. The user may not even know that they made a mistake and will start to wonder why they haven't received a response. It is less likely that a user will accidentally mistype their e-mail address twice in a row.
My code has certain dependencies. If there is no e-mail address, there will be no from line in the e-mail, which will obviously be a problem.
Validation is the key to coder (and user happiness) when a form is involved. Sometimes it seems like a lot of effort and even overkill, but, in the long run, it will save a lot of headaches.
![]()
May 21, 2008
a link to a really cool website that has a ton of pre-built regular expressions (see the "Regex Library" link to the right). http://regexlib.com is the site if I happen to remove it from the links at some point.
a contact me page, which is also why I found the regular expressions website.
a flash photo gallery of photos that I have taken.
About the regular expressions
I am not going to pretend to know the history of regular expressions. I do know
that they did not originate from Microsoft, although they are included in the
.Net framework. Regular expressions, in a nutshell are an extremely efficient
way to validate or pattern match strings. I used them to validate input on the
Contact Me page. For example, the regular expression for first name on the
Contact Me page is:
^[a-zA-Z]+(\-[a-zA-Z]+)?$
That regular expression basically makes sure that you only enter upper or lower case english letters (no spaces, periods, etc...), which, if you wanted to get picky is not very culturally friendly. Nor is it friendly to people with suffixes (e.g., Jr.) or prefixes (e.g., The Honorable). But, hey, I have to draw the line somewhere and this is not a commercial site.
Anyway, regular expressions are a little archaic and hard to understand, but nothing beats them when it comes to validating or pattern matching a string.
About the Contact Me page
The contact me page sends an e-mail to me using a visual basic code behind and
the .Net System.Net.Mail namespace. I wrote code to reformat the input fields on
the Contact Me page into an e-mail and send it to me. The VB code-behind and the
regex validation make it relatively secure. That is, the average joe developer
wouldn't be able to hijack my e-mail. There are a few more things I could do to
improve the security, which I will do at some point.
Interesting thing that I discovered while setting up the Contact Me page was that my ISP blocks Port 25. For quite a while, I couldn't figure out why my e-mails weren't going through.
About the Flash Photo Gallery
I dusted off my Actionscript knowledge today. I haven't written any Actionscript
since 2.0 and we are currently on 3.0, which, I discovered was quite an
overhaul. I spent quite a bit of time coding the photo gallery...getting the
timing correct, figuring out how to dynamically load pictures so, I don't have
to rewrite the code everytime I want to change a picture, etc...
One thing about Actionscript is that syntactically, it seems to be a blend of C# and VB, but obviously the built in functions emphasize graphics and motion. I haven't tried Silverlight yet, but I can't imagine it will take Microsoft very long to catch up to Flash's capability.
Another note about the flash photo gallery...I could have very easily used some website with flash photo capability to display my pictures. There are about a zillion of them. I didn't for a few reasons.
First, I have very specific size and flexibility requirements. 190 x 127 is the size of each picture. No more no less.
Second, I wanted a unique look. Granted, there isn't really anything special about the Flash photo gallery, but the color scheme matches mine and the beveled edges are cool.
Last, I wanted to get some more practice at Actionscript and mess around a bit with the new 3.0. While I did look at a lot of sample code to help me write the photo module, my code is original...no copying.
![]()
May 20, 2008
.NET Version for this Website
Yesterday, I spent most of the day converting the website to ASP.NET. I am
working on a few additional pages to add and discovered, while testing them,
that my host runs .NET version 1.1. Definitely not good enough. So, this
morning, I transferred to a new host (which should take effect in the next 24
hours) and will be runninng on .NET 3.5 and Windows Server 2008.
Why does the version matter?
VB.Net was pretty much a complete rewrite of the Visual Basic coding language.
Although there are some similarities between VB 6 and VB.Net, there are a lot
more differences. VB.Net is a fully featured object oriented coding language
that parallels any other .Net enable language (like C#). .Net version 1.1 was in
the line of first major releases for .Net and the newly rewritten visual basic.
So, as you can imagine, considering we are on version 3.5 currently, Visual
Basic and .Net have been enhanced quite a bit since then. Most of the code I
wrote yesterday doesn't work on .Net version 1.1
What version of .NET are we on?
We are currently on version 3.5. Version 3.0 came out with Windows Vista. Version 3.5
was released this year with some major new enhancements that I am still trying to
figure out.
The Naming Convention for Visual Basic
As usual Microsoft has thoroughly confused people with it's naming convention.
Technically, there is no Visual Basic .Net. That was the original name of the
revised Visual Basic language when .Net was first released. However, Microsoft
later dropped the .Net and added the release year. So, with the latest release
of .Net and the related developer tools, we are now on Visual Basic 2008.
What about SQL Server?
SQL Server 2008 was originally intended to be released with the most recent
set of releases. It fell behind schedule, though. So, as of now, the most recent
release of SQL Server is SQL Server 2005. SQL Server 2008 will be released
sometime this year, at which time there will be a service pack for .Net to add
the new SQL server 2008 functionality. I tried installing the latest developer
release of SQL Server 2008 on my Windows 2008 Server and ran into all kinds of
problems. The biggest one was that I couldn't install SQL Server 2008 under a
domain controller. I got around it, but what a pain.
![]()
May 19, 2008
A systems implementation in just about any organization is frought with problems. They are almost always behind schedule, overbudget, and frequently canceled at the last minute.
I was lying in bed late last night thinking about how the typical small-scale systems development project in a small company might evolve.
Tim (from Accounting): "Doug I need help with a spreadsheet I am working on. I am trying to automate some of the manual work I do each week for the CFO reports and am having some difficulty with the formulas. Is this something you can help me with?"
Doug (from IT): "Sure no problem Tim."
(After reviewing the spreadsheet)
Doug: "Tim, this spreadsheet is a mess. I can see what you were trying to do with it, but most of this stuff could be easily automated in a database with one or two report queries. You wouldn't have to do anything except load your data into the database each week and run a couple reports. What now takes a couple of hours each week would only take a couple of minutes. Give me a couple weeks and I will have something for you to use."
Tim: "Awesome! Thanks!"
(a week later)
Tim: "Doug, Rob and Susan from finance both have a couple of spreadsheets they would like to automate too. Do you think you can take a look at them and see if it can be added to the database you are building for me?"
Doug: "Sure Tim, but it is probably going to add a couple of weeks of development time and I have another project starting in a month."
(3 weeks later, Doug delivers the project to Tim, Rob, and Susan)
Tim: "This is fantastic, but the reports aren't in the format that we give to the CFO. I'm going to have to spend a few hours each week putting them in excel and reformatting them."
Doug: "Well, that's how long you spent each week in the first place. Give me a week or two and I will see if I can put them in the correct format for you. My other project will have to be put off a week or two."
(1 week later, Doug delivers the revised reports to Tim)
Tim: "Great! This is perfect! I meant to stop by and tell you, though, some of the data changed. When I upload the data it gets all goofed up. I think it's because we are getting it from a different source now."
Doug: "Yep, a different source would do it. How often does the data change?"
Tim: "About once a quarter."
Doug: "Ok. I'll have to modify the data import to be flexible enough to adjust when the data changes. Give me a couple of weeks and I'll have that for you so you won't have to come back to me everytime the data changes."
(a month later, Doug delivers the revised functionality to Tim)
Tim: "Great! Thanks Doug!! We're only going to need this for another couple of weeks though, because our CFO decided to buy some financial software that does all this for us."
Doug: "@#$! He didn't tell me that. What did he buy? Has he thought about how it's going to be implemented? Who is going to support it? Our hardware hasn't been upgraded in a long time. Who knows if it's capable of running whatever he bought."
Tim: "Um, I dunno. I guess you'll have to talk to him."
(Doug sobs)
Even something as simple as automating a spreadsheet turns into a two month long project that eventually ends up getting trashed. Poor communication, lack of user requirements and a complete disregard for a business needs analysis doomed this project from the beginning.
EVERY project, no matter how big or small, must go through some form of requirements process if it is going to be successful. Even small, seemingly innocuous requests from users can turn into a huge waste of time and resources if not properly prioritized and evaluated for business need.
![]()
May 9, 2008
Certifications and Education
Below is some information about a few of the certifications and educational opportunities I am currently pursuing.
Masters of Information Systems
I recently applied to and was accepted at Phoenix University's Masters of Information Systems part-time remote program. If you are interested in the program, you
can read about it here. My
first class starts on May 20 and I will be spending about 8 hours a week studying and participating in online classroom activities.
Microsoft Certified Technical Specialist (MCTS)
I am currently studying for the MCTS certification from Microsoft. If you are interested in the certification, you can read more about it
here. I have a couple of thousand page books to help me prepare for the test and a lot of videos. I
have gotten through about half of it so far.
UML 2.0 Fundamental Certification
I am also working on learning UML 2.0 (Universal Modeling Language) and plan on getting the
OCUP Fundamental certification in this as well. I have a couple of books
on the subject and have already read through most of the official current specification.
![]()
May 8, 2008
The new DougHemminger.com
Today I am rolling out the new, redesigned DougHemminger.com. So far, it is excessively simple. As of now, there isn't even a link to another a page...there is just the main page.
What am I doing these days?
I am currently spending between 6 and 8 hours a day studying things like VB 2008, SQL Server and ASP .NET (to name a few).
PhotoAccess Project
I have already spent about 2 months studying VB 2008, ASP and the whole .NET 3.5 environment. I would really like to put it in practice. So, I am going to create a software program that stores
photographs on a database and allows users to reference them through the internet or through a distributed network application. Initially, they won't be allowed to add or delete photographs (I
have reserved that functionality for a windows maintenance gui application). However, I would like to allow users to assign keywords and categories and search the photos based on those keywords
and categories.
I started the project by creating a simple design drawing in Visio. However, I realized that I have a lot to learn about the requirements and analysis process. So, I spent some time researching various methodologies and settled on the IDEF1X methodology for documenting and building the requirements for the database. The rest of the software will be documented using UML.
I have never really used either of these methodologies, however and need to learn them. So, I printed out the formal specifications and ordered a couple of books.
I am going to start with the database analysis, not only because I think it makes sense to start with that before the software analysis, but also because I think the IDEF1X methodology is a lot easier to learn and understand. It may also help me get a jump start on UML once I am ready to dive into it.