Writing a Windows Service--Warts and All(1/21/2007) Writing a Service
1. When Do You Need A Service? (Beautiful Things)
You need a Windows Service when:
- You need a process to be running whenever the computer is up...a service auto runs whenever the computer is up or calls for it.
- You need a process to run in the background without the user knowing it is there. A service runs in background -- without user knowing it exists.
- You need a process to run without any user intervention. A service, by definition has no GUI...it runs without a GUI--no user intervention, ever.
- You need a "server" of your own to run in the background. Examples of servers running as services are Exchange, SQL, ISA, etc.
-- Back To Top of This Page --
2. What Do You Need To Know? (Some warts)
- There is no GUI
Configuration must be done externally Any user interface must get data contact via a service-output file. - There is no registry
- Classes may not work as you expect in a Windows or ASP app
- SQL and File System are available, but permissions can be a problem to get setup and going
- Limit your service to keep a tight focus on what it should do, when, and how.
- Remember...no one will know right away if it fails.
- You must take steps to prevent constant reporting of things like network failure.
- Installing/uninstalling the serice is awkward (see below: Install your service and Uninstall the Service)
-- Back To Top of This Page --
3. The Dev Platform (Recommendations)
- Begin by writing a Windows Forms App. Build your program and make it work without bugs.
- Debugging is easier. System delays are avoidable. Quick, easy executions are achieved here.
- Lets you work in the environment you're more familiar with.
- Be sure to include timers and test it to work with them, too.
To make your program work "into" a service, you'll normally need only 2 buttons--one to run with and one to run without normal delay.
Your VB Code will need to include handlers for your 2 GUI buttons, a timer, a SetupService routine, and a CloseService routine:
(In globally-accessible data)
Dim WithEvents MyATimer As Timers.Timer 'for normal processing time interal
'have button 1, for w/out delay do one thing--call GoDoSomeActualWork 'have button 2, for w/norm delay, do 1 thing--call SetupService
'This sub is where the actual service code begins---------------------------------- Private Sub SetupService() ' Here, place code to initialize and "setup" your service MyATimer = New Timers.Timer AddHandler MyATimer.Elapsed, New _ System.Timers.ElapsedEventHandler(AddressOf Me.myAtimer_Elapsed) ' ......... your setup code MyATimer.Interval = 60000 'in milliseconds MyATimer.enabled = true end sub
Private Sub CloseService() ' Here place code to close down the service Me.Finalize() End Sub
Private Sub myAtimer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) ' Here run your actual code by calling a sbroutine to do just that GoDoSomeActualWork() MyATimer.Interval = 12000 'in milliseconds MyATimer.enabled = True 'Don't forget to restart your timer to do it again end sub
Private Sub GoDoSomeActualWork() 'here is where you do the actual work end sub
|
-- Back To Top of This Page --
Consider this code. First, when a server (or a desktop) starts, there is a period of time while things are getting started. During this period of time, which can be up to 10 minutes or even more on some servers, your service may not work very well. Consequently, you need to have a delay before you let your service really get going. In our example, we setup "MyATimer" for this purpose.
In the SetupService routine, we
- instantiate an instance of MyATime as a timer,
- we add a connection from the timer to the handler routine,
- we set an interval of 10 minutes,
- and, finally, we start the timer.
When the timer runs down, i.e., the timer interval has elapsed, we will first hit the routine named "GoDoSomeActualWork." Whatever that routine does, it will do and then we'll return to restart the MyATimer timer with a 2-minute interval. (Which means that in 2 minutes we will "GoDoSomeActualWork" again in the never-ending cycle that really is our service.
It is not uncommon for a service to use 3 or 4 timers depending upon what events occur.
-- Back To Top of This Page --
You will normally need to add one more routine to your service-to-be. Most services you will write will need to write to the event log
- So you can know when the service starts--note that if the service is set for auto-logging, it will do this automatically.
- So you can know if something goes wrong or one of various events occur
- So you can know when the service stopped--note that if the service is set for auto-logging, it will do this automatically.
This means you need to add a subroutine something like this:
#Region " Write an error message to the system event--application log "
' Args: ' First arg ' 0=Information message (service started, stopped, etc.) ' 1=ERROR message ' 2 = Warning message ' 2nd arg is the text description of the error ' 3rd is an error number we can use to reference it in the docset and program ' e.g. PostEventToSystemLog(0,"ITSBITS® Job-1 Services Monitoring started",100)
Private Sub PostEventToSystemLog(ByVal eType As Int16, ByVal sMessage As String, ByVal nErrNum As Int32)
Dim entryType0 As System.Diagnostics.EventLogEntryType = EventLogEntryType.Information Dim entryType1 As System.Diagnostics.EventLogEntryType = EventLogEntryType.Error Dim entryType2 As System.Diagnostics.EventLogEntryType = EventLogEntryType.Warning
' The first entry is the name of the log you want to write to. The second ' parameter is the machine name. In this case it is the local machine name. ' The third parameter is the source of the event. Commonly this is set equal ' to the name of the application that is writing the event. Dim ev As New EventLog("Application", My.Computer.Name, "YourServiceName") ' The first argument to WriteEntry is the text of the message. The second ' argument is the type of entry you want to create (Warning, Information, etc.) ' The third is the eventID of the event. The user could use this to look up ' further information in a help file. Select Case eType
Case 0 ev.WriteEntry(sMessage, entryType0, CInt(nErrNum)) 'info Case 1 ev.WriteEntry(sMessage, entryType2, CInt(nErrNum)) 'err Case 2 ev.WriteEntry(sMessage, entryType1, CInt(nErrNum)) 'warning Case Else 'default to a warning ev.WriteEntry(sMessage, entryType1, CInt(nErrNum))
End Select ev.Close() 'now let's clear memory ev = Nothing entryType0 = Nothing entryType1 = Nothing entryType2 = Nothing
End Sub #End Region
|
-- Back To Top of This Page --
4. The Actual Service
1. In the Visual Studio IDE, FILE >> NEW >> Project >> VB >> Windows >> Service
Name the service so it ID's what it is.
2. Add a Service Installer and Service Process Installer to your application:
- In Solution Explorer, access Design view for the service
- Rt. click the background of the designer and then click "ADD INSTALLER" option
(2 objects are added--ServiceProcessInstaller and ServiceInstaller
- Click the ServiceInstaller component just added. Be sure the NAME property is the same as that shown in the designer
- Set property for StartType, DisplayName, Description, ServiceName:
- StartType = Disabled, Manual, Auto. Manual says that if a service is called for, it is to be started. Otherwise, it does not run.
- DisplayName = The name of your service. Recommendation: make it the same as you used in step 4-1 above.
- Description = Look in the Microsoft Management Console >> Services.
Notice how most services have a brief--usually a sentence (or maybe 2) description of what they do. Enter such a description for your new service. - ServiceName--Recommendation: make it the same as you used in step 4-1 above.
- If your new service will depend upon any other services, use the drop-down to enter the EXACT names of those services.
- For ServiceProcessInstaller, set properties, including security info for the new service:
- Account (Security for your service):
Normally, we use "LocalSystem" which means the service will run under the local system's control and auspices regardless of who is logged on, etc. In other words, the service will run in the context of an account that provides extensive local privileges, and presents the computer's credentials to any remote server. You can use a user account, but there are always problems when a service runs only under a user account...not normally what you want to do. The service will prompt for a valid user name and password when the service is installed and runs in the context of an account specified by a single user on the network
You can also run under the NetworkService control--use this when the service needs cross-network control. The service will run in the context of an account that acts as a non-privileged user on the local computer, and presents the computer's credentials to any remote server.
You can run as a "LocalService" and this works well, too. The service will run in the context of an non-privileged user on the local computer and presents annonymous credentials to any remote server.
- Leave other settings alone.
- Move to your code:
- Use ALT-View-Code to get to the VB code-behind for your app.
- Notice that you have only a few lines showing. This will look like this:
| Public Class Service1 Protected Overrides Sub OnStart(ByVal args() As String) ' Add code here to start your service. This method should set things ' in motion so your service can do its work. End Sub Protected Overrides Sub OnStop() ' Add code here to perform any tear-down necessary to stop your service. End Sub End Class |
- Now copy and paste in the Imports (and any pre-program comments) from your windows dev program ahead of the "Public Class Service1" line
- Now copy all lines from the windows dev program starting with lines:
'This sub is where the actual service code begins----------------------------------
Private Sub SetupService()
and going all the way through the "End Class" line to the clipboard. I.e., highlight them, then use EDIT >> COPY
- In your new service, highlight the "End Class" line at the bottom of the file and then use EDIT >> PASTE to put your program code into the new service.
- In the OnStart suboutine, type "SetupService()"
Protected Overrides Sub OnStart(ByVal args() As String)
SetupService()
End Sub |
- In the OnStop subroutine, type "CloseService()"
Protected Overrides Sub OnStop()
CloseService()
End Sub |
- In the IDE, select the tab for YourServiceName. You should see several tabs down the left side of the IDE with the first being "Application." Click the Application tab. Pick the icon you want to associate with your service. Set the Startup Object as "Sub Main."
- Use EDIT >> FIND >> REPLACE. Change "Service1" to "YourServiceName" in the "Current Project." There should be 3 changes.
- In the IDE, click the YourServiceName.vb[Design] tab at the top of the work area.
- Right-click in the gray area and select Properties.
- Most often you will want to add event-log-events from your own code. The default for "AutoLog" is "True" but you can set it to false now. If you leave it set to true, Windows will add start and stop events to the Applications Event Log automatically.
- Recommendation: Set CanPauseAndContinue to True (False is the default) for testing purposes. Set CanShutDown to True (False is default). You can reset either or both of these and recompile once you get your service working just as you want it to--do that when you move from Debug compilation mode.
6. Check that you got what you expected and then save using File >> Save All
7. Use Build >> Build yourservicename to be sure the code compiles OK. This does not preclude run-time errors, but it will show you what you may have tried to use that the compiler can let you know about.-- Back To Top of This Page --
Build Your Service-Install Shortcut in WindowsXP
Purpose: to place a shortcut on your desktop that you can use repeatedly to install/uninstall your service while you build and test it.
- Minimize all windows so you see the desktop.
- In a "blank" area of the desktop, rt-click. Select NEW >> SHORTCUT to bring up the "Create Shortcut" wizard.
- For the location of the item, enter:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe
click NEXT
- Give your shortcut a name--may we recommend "Service Installer." Click FINISH.
-- Back To Top of This Page --
Place a CMD Prompt and Windows Explorer on your desktop (WindowsXP)
Purpose: You must install/uninstall your service using a command prompt. It makes it a lot faster and easier if you have this on your desktop.
- On the Windows Start menu, click ALL PROGRAMS >> ACCESSORIES
- Find COMMAND PROMPT, Hold down your Right Mouse Button and drag the COMMAND PROMPT to the desktop near your new Service Installer shortcut.
Release the mouse button. - Click on "Copy here."
- Repeat for "Windows Explorer"
-- Back To Top of This Page --
Install your service
- In WindowsXP:
- Open Windows Explorer and find your program. It will normally be under your "My Documents" in a folder something like: My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug
and it will be named as YourServiceName.exe (where YourServiceName is the name you gave it way back up in step 4-1.) Size your Windows Explorer window so it takes up only a small part of your screen.
- Open your Command prompt.
- Holding down your left mouse button, drag the Service-Install Shortcut onto the Command Prompt. Type a single blank onto the screen.
- Holding down your left mouse button, drag the service file, YourServiceName.exe, from the Windows Explorer onto the command prompt.
- Hit the ENTER key and wait. Your screen should look like what's shown below:
- In Windows Vista:
- Open Notepad and build a file that looks something like this:
REM This is SMserviceInstaller.bat REM This will install your ITSBITS-Job-1SM service REM To remove it, use this with an R argument. C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe "c:\users\Wallace C. Allison.itsbits\documents\visual studio 2005\projects\Job1Service\Job1Service\bin\debug\ITSBITS-Job-1SM.exe" -%1Pause |
Note that you need to use your own name for this file instead of SMServiceInstaller (but do use the .bat extension) and your own project name instead of Job1Service....Job-1SM.exe, which is the windows service file executable you created above. - Save this as c:\YourNameInstall.bat but keep Notepad open.
- Now go to your desktop and right-click >> NEW >> Shortcut.
- In the "Target" textbox of the new shortcut wizard, type "c:\YourNameInstall.bat"
- Click OK and give your new shortcut a name you'll easily recognize, i.e., MyService1 Installer
- Back in Notepad, add " R" to that horribly long line.
- Save this as c:\YourNameUnInstall.bat.
- Close Notepad
-
- Now go to your desktop and right-click >> NEW >> Shortcut.
- In the "Target" textbox of the new shortcut wizard, type "c:\YourNameUnInstall.bat"
- Click OK and give your new shortcut a name you'll easily recognize, i.e., MyService1 UnInstaller
- Test the Install
On the desktop, double-click the Install shortcut you just created. Your screen should look something like what's shown below
Microsoft (R) .NET Framework Installation Utility Version 2.0.nnnnnnnnn.nn Copyright (c) Microsoft Corporation. All rights reserved.Running a Transacted installation. Beginning the Install phase of the installation. See the contents of the log file for the ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe assembly's progress. The file is located at ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.InstallLog Installing assembly '...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe'. Affected parameters are: logtoconsole = assemblypath = ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe logfile = ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.InstallLog Installing Service YourServiceName... Service YourServiceName has been successfully installed. Creating EventLog source YourServiceName in log application... The install phase completed successfully, and the Commit phase is beginning. See the contents of the log file for the ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe assembly's progress. The file is located at ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.InstallLog Committing assembly '...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe'. Affected parameters are: logtoconsole = assemblypath = ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe logfile = ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.InstallLog The Commit phase completed successfully. The transacted install has completed. |
Be sure to check the report. If something fails, the last two lines may say exactly the same thing, but in the report itself you will find that something failed and the install is being rolled back. In that event, you will have to trouble shoot the problem. -- Back To Top of This Page --
Start Your New Service
- In the Windows Start menu, hit Run and enter "MMC" (no quotes) to run the Microsoft Management Console
- If you don't already have a Services and Event log plug-in setup for the MMC, create one now:
- FILE >> ADD/REMOVE SNAPIN
- Click the ADD button
- Find Event Viewer in the "Add Standalone Snap-in" window and click it to highlight it. Then click the "ADD" button. Select "Local Computer" and click the FINISH button.
- Find Services in the "Add Standalone Snap-in" window and click it to highlight it. Then click the "ADD" button. Then click the "ADD" button. Select "Local Computer" and click the FINISH button.
- Click the CLOSE button.
- Click the OK button.
- Maximize the "Console Root" window in the MMC.
- Click FILE >> SAVE AS. In the "Save As" window, enter the name "Events and Services" and click the SAVE button.
- Click the small + by the Event Viewer (Local) to expand it.
- Click "Application" to see the Application log. You may want to clear this log--or not. If you do, you can right-click on "Application" and pick the option to clear all events. Notice that this will make your work easier, but it will also mean losing any and all logged events.
- Click on "Services (local)" to show all services in the right-hand pane.
- On the bottom of the right-hand pane, click "Extended" if it is not already the selected option.
- Find your new service in the list of services and click on it. Notice that it is not started.
- Notice that at the upper-left of the right-hand pane you see the name of the service and the description you have entered for it. You will also see the offer to "Start the service" there. Click on this link to try to start your service.
- Now click on the "Application" to see the Application Events Log. You should see that your service started or you may see one or more errors it generated.
-- Back To Top of This Page --
Stop Your New Service
- In the Windows Start menu, hit Run and enter "MMC" (no quotes) to run the Microsoft Management Console
- Use option FILE >> OPEN and select "Events and Services"
- Click on "Services (local)" to show all services in the right-hand pane.
- On the bottom of the right-hand pane, click "Extended" if it is not already the selected option.
- Find your new service in the list of services note that it is "started" which means it is runnin. Click on it.
- Notice that at the upper-left of the right-hand pane you see the name of the service and the description you have entered for it. You will also see the offer to "Stop the service" there. Click on this link to try to start your service.
-- Back To Top of This Page --
Uninstall the Service
(Be sure the service is stopped first. See above.)
- In WindowsXP:
- Open Windows Explorer and find your program. It will normally be under your "My Documents" in a folder something like: My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug
and it will be named as YourServiceName.exe (where YourServiceName is the name you gave it way back up in step 4-1.) Size your Windows Explorer window so it takes up only a small part of your screen.
- Open your Command prompt.
- Holding down your left mouse button, drag the Service-Install Shortcut onto the Command Prompt. Type a single blank onto the screen.
- Holding down your left mouse button, drag the service file, YourServiceName.exe, from the Windows Explorer onto the command prompt. Type "/U" (without quotes) so it is at the end of the line.
- Hit the ENTER key and watch as the system uninstalls the service. Your screen will look like this:
- In Windows Vista
- On the desktop, find your uninstaller shortcut and double click on it to launch it.
- The screen should look something like that shown below:
Microsoft (R) .NET Framework Installation Utility Version 2.0.nnnnnnnnn.nn Copyright (c) Microsoft Corporation. All rights reserved.The uninstall is beginning. See the contents of the log file for the ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe assembly's progress. The file is located at ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.InstallLog Uninstalling assembly '...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe' Affected parameters are: logtoconsole = assemblypath = ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.exe logfile = ...My Documents\Visual Studio 2005\Projects\YourServiceName\YourServiceName\bin\Debug\YourServiceName.InstallLog Removing Eventlog source YourServiceName. Service YourServiceName is being removed from the system... Service YourServiceName was successfully removed from the system. The uninstall has completed. |
-- Back To Top of This Page --
Before You Debug
You must uninstall and reinstall the service before any changes to it will become effective. For that reason, it is convenient to simply minimize your command prompt and Windows Explorer windows. You will find that once you have done and install/uninstall, you can use the up/down keys to simply repeat the desired procedure...thus making it easier and faster than it might otherwise be.
Invoice Me
-- Back To Top of This Page --
Buying A New Computer--Here's What You Should Know
(12/25/2006) So, you want to buy a new computer, but you've heard that Microsoft's new Vista® operating system is on the way and you're not quite sure what that means to you. Well, here's a word of help for you.
First, to answer a question that numerous people seem to have, yes, Vista® is real. It is RTM (released to market) for big customers even now and sometime very soon all new computers from your favorite manufacturer will come with the new OS. In January, it will be RTM for general retail distribution.
Second, yes, Vista® will include numerous improvements that will make it worthwhile for many users. It will have better security, stronger graphics than ever before, and lots of new capabilities. That's the good news, but it brings new requirements, too...read on.
Now that we've established those things, what about all the articles out there that say now is the time to buy to save a bundle. That may be true. It may not. The question becomes whether you actually need all that new stuff during the next, say, 3 years. If the answer is yes, then this part of the conversation is mute--you need to wait just long enough to get Vista® to have that. On the other hand, if for a couple or three years all you will use this computer for is going to be email, a little surfing of the net, maybe some word processing and playing a little music, it is a great time to save some money. You can get a great bargain on a 32-bit-processor computer with Microsoft Windows® XP. Download the latest IE7 and enjoy.
But, what to do if you're not sure of the usage you'll want or need? Then you can take a middle road. Here's what to do and why. First, the new OS and lots of new software that's in the pipeline right now need a 64-bit processor. Within a couple of years all new releases will be designed strictly for a 64-bit processor. So, you need to purchase a 64-bit processor--avoid the Intel Itanium because it doesn't qualify, even though it's often called a 64-bit processor.
Now, realize that much of what's new and great in the computer world revolves around a new batch of graphics processors. There's the problem with lots of the machines you can buy right now. Their graphics cards aren't up to the task presented by Vista® and you will have to buy a new graphics card later to really use the new OS. It's hard to say what that will cost you, but a guess would be $100 to $350 dollars--depending on how serious you are about graphics work (but excluding true graphics pros who will pay much more--you know who you are.) There are 3 kinds of labeling on the market right now that can affect what you want to buy--especially in a notebook.
- No label--just pass it by no matter how good a bargain it appears to be
- Vista® Compatible--pass it by. The video card will let you run Vista® but it won't be able to do lots of things you want it to.
- Vista® Ready--OK! This one has a video card that can handle the new OS's most complex video needs. This is the one you want.
Finally, there's the questions of memory and hard-drive space. In over 30 years of IT work there are two complaints I have never heard from anyone. First, I've never heard anyone say, "Darn it--I bought too much memory." They always say, "How much will it cost me to upgrade my memory?" Second, and in a similar vein, I've never heard anyone complain, "Dang, I bought too big a hard drive." It's always more like, "Can you put a bigger hard drive in my system?" There's a message here, but I'm going to let you figure out what it is. OK?
Finally, let's look at 2 other things to note. Many of the new notebooks will not be equipped with either a floppy drive or a serial port, though they will almost all come with a built-in modem. Normally, this is not a problem, but if you need a floppy drive or a serial port for any reason, the absence of it becomes a problem very quickly. So, look before you leap. You may need to budget for a USB-driven floppy drive or serial-port adapter. Or, of course, it may be time to budget for a new printer.
There are 4 "flavors" of the new OS. You can see what the differences are by hitting this link Features
®Microsoft Windows and Vista are registered trademarks of the Microsoft Corporation.
Cost to use this article is $ 25
Invoice Me
-- Back To Top of This Page --
ITSBITS® is registered in the U.S. Patent and Trademark Office
Content on this page is ©2006 by Wallace C. Allison. All rights are reserved under all applicable copyright laws.

50%-70% Off Store Prices Save Money on Liquidated Merchandise Buy in quantity to get the best prices!Use Discount Code LC36007 at www.PayJustHalf.com |
|
| Designed for and best viewed with Microsoft Internet Explorer |