Archive for July, 2007
As you may know, Windows Services developed in .NET can’t be run with the Visual Studio .NET environment. Instead, you have to install the application as a service, so that it can run under the Windows Services Control Manager, and attach the Visual Studio debugger to the process. The catch is that the service has to be running before you can debug it and this makes it difficult for you to debug your start-up routines.
In this article I’ll examine some techniques you can use to make debugging your Windows Service apps easier
The first technique I like to use is scaffolding. This means that I first develop the app as a standard Windows application, either WinForms or Console, and develop a substantial portion of the program without having to deal with the baggage of the service environment. I use very simple code for the scaffold that essentially emulates the standard service, such as the Start, Stop, Pause, and Continue commands. Each part of the program can be tested as it is written this way as long as you’re using a good design.
Unfortunately, not every service application can be built up this way since some need to run as a service in order to do what they need to do properly. Also, you need to be mindful that your scaffold app will be running under your user account, not the NETWORK or LOCAL services accounts, so the rights are very likely to be different. Security issues are a common stumbling block when it come to running as a service.
Once the units of your program are in place you’re ready to deploy it and run it as a service. However, you will probably still need to debug it. To do this, you install and start the service and attach to it using the Attach To Process dialog from the Visual Studio Debug menu. Now you’re ready to set your breakpoints and debug the app but there are still some challenges involved in debugging a .NET service application.
First, the service has to be running for you to attach to it. This means that by the time you can hook into it the startup code has already been executed. If you have a problem in the startup code, code that executes in either the Main or OnStart methods, this can be difficult to debug. Also, since the attachment process doesn’t stop or pause the service but suspends the service thread, this can cause some odd effects on some code. Also, you can’t use pausing techniques to have the program wait on you because Windows only provides a 30 second stretch of time for a service to start. If it hasn’t completed its start during that time, it program won’t start. You can use logging to disk to capture some of these errors but that can be difficult and tedious to manage.
My method for getting around this problem is to have very little code in the startup routines themselves, like so:
Protected Overrides Sub OnStart(ByVal args() As String)
ServiceStartUp()
MyBase.OnStart(args)
End Sub
Then, to enable debugging, I move this call, ServiceStartUp(), to the OnContinue method and comment it out in OnStart. That way I can start the service without any code being executed, pause the service, set breakpoints and attach to it from within Visual Studio, and click to allow it to continue. I can then debug the startup code of the application.
Make sure that you uncomment the startup line in the OnStart method when you’re ready to deploy though!
One other tip is how to find your app in the Attach To Process Window. This can be confusing at first. The default setting of the dialog only shows processes for the currently logged in user so your service, which is mostly likely running under a system service ID, won’t be visible although you’ll see a grayed out copy of the matching project in the list. Check on the “Show processes from all users” box to see the process you want. Don’t let the similarly named “vshost” file confuse you.
If you have any questions or ideas about debugging .NET Windows Service applications, please leave a comment here.
Share This Article:
These icons link to social bookmarking sites where readers can share and discover new web pages.
July 24th, 2007
I’ve made a few more changes to the site today.
First, you may have noticed that I’ve placed the full article on the front page rather than just an excerpt. Although my articles are usually long, I’ve heard that some people prefer to have everything on one page. Also, doing it this way allows my RSS feeds to be full, rather than partial. For now, the 5 most recently published full articles will appear on the front page. Let me know if you like this change.
While I’ve had them from the start on individual pages, I also have added the post rating and social bookmarking icons to the front page as well. If you enjoyed an article, please leave a rating for it. If you didn’t, please don’t, just kidding, but if you didn’t like an article or saw a problem with it please leave me a comment as well.
And finally, a note on one of my sponsors, Auction Ads. They’re a new service that plugs into eBay and shows items that are currently up for sale. On my pages, I picked “Visual Basic” as the keyword so that you should, in theory, see a list of auctions for VB related items. I know a lot of people look for old copies of VB6 and earlier and hopefully these ads will give you a heads up on them. Unfortunately, Auction Ads is having growing pains so you may see purses, iPods and the infamous Legos and teddy bears instead unless you refresh the page. Hopefully they’ll get this cleared up soon.
As always, I appreciate any suggestions or questions you might have so feel free to leave me a comment.
Share This Article:
These icons link to social bookmarking sites where readers can share and discover new web pages.
July 24th, 2007
What is a scapegoat? It’s a metaphor derived from the ancient Hebrew practice of placing the sins of the nation upon a sacrificial goat who was sent into the wilderness. In modern times, it refers to someone who is blamed for misfortunes as a way to distract attention from the real causes. In software development teams scapegoating of a team member (or members) usually happens because of a breakdown or lack of good procedures and processes. These are almost always associated with failed teamwork and leadership.
What Causes Scapegoating?
Scapegoating usually begins as a result of pressure on a team that occurs when things begin to fall apart during a project. For example, a development team doesn’t use version control and a key update is lost. Logically, it would be a lack of good process by the team as a whole that caused the problem. However, often people find it more comforting to find someone to assign blame to, preferably someone politically weaker in the organization than themselves. The typical end result is the firing or reassigning of the ‘goat’. However, this does not address the underlying fault so the team is doomed to repeat the cycle again and again.
In fact, scapegoating can become so bad in a department that people group themselves together in ‘alliances’, almost like a reality game show, to defend themselves. One group fights another, people get angry and stressed, people get fired, but what doesn’t happen is much work. Everyone is too busy fighting a nasty political game to get things done. In the worse case scenario, this problem infects management and even the rest of the company.
Another contributing factor to scapegoating are misguided and improperly implemented human resources policies like 360 degree performance appraisals or forced ranking. While these programs might be of value in some cases, most of the time they only increase the dog-eat-dog atmosphere in a dysfunctional team or company environment. These systems really fall apart when management has begun the ‘blame game’ along with the employees under their supervision by taking sides.
What are some signs that a team is moving into scapegoatism?
One of the early warning signs is when one, or maybe two, people are ostracized by the group or are shown obvious signs of disrespect. For example, people on the team make a point of not inviting a person to lunch when everyone else is going or openly use disrespectful language toward a person on the team. If a team lead or manager allows this kind of behavior to continue it will escalate into more serious problems ranging from lost productivity to workplace bullying.
Another sign that the team is moving in this direction is the formation of cliques within the group that seem always to be at odds with each other. While it is natural for people to hang out with other people they like at work this can become unhealthy to team dynamics if it begins to take on an ‘us against them’ mentality. This typically reaches a boiling point when a lead or manager is given the choice of deciding who was right in a conflict. Often there are no right answers and a quick decision one way or the other results in a loss of credibility and respect for the manager.
What can a team lead or manager do to prevent this problem?
The main thing to do is address the underlying causes of the situation. Since these are almost always process related things that cause stress in the team take the time to assess this area. Do you have process areas that need improvement? If so, work on correcting them. If you don’t think you do, check again, because you probably have overlooked something. Are human resources policies causing problems in the team? Lobby to exempt the team from them, at least temporarily. You are the ’spear catcher’ for the team and you should protect them from outside productivity killers. If the situation has already become so toxic that making these changes is impossible, then you may want to prepare your resume because things can only go downhill from here on out.
Watch out for people blaming others for problems, particularly unjustly or in a derogatory or gossipy manner. Urge team members to criticize the process not the person. Ask them what can be done to improve the process and keep them focused on this and not on the scapegoat. As team lead, you should avoid playing favorites when it comes to assigning work and socializing. If people under you are having problems, mentor them, find out what the problem is and look for solutions to the situation. Don’t write them off as worthless and give in to the desire to blame them for the team’s woes or use them as a pawn for the next round of downsizing.
Another important thing is not to ignore the problem. Some managers find it easier for them to ignore these kinds of problems and push them under the surface by ignoring communications or by not making any changes that would help relieve the problem. They may think that they’re not taking sides in a conflict and are staying above it but actually all they’re doing is simply abdicating their role as leader of the team or department. As manager, it’s your responsibility to take care of these problems, not to sweep them under the rug.
What are your ideas on this topic? Have you ever worked in an organization where scapegoating got out of hand? If you do or have, leave a comment about it.
Share This Article:
These icons link to social bookmarking sites where readers can share and discover new web pages.
July 21st, 2007
My discussion with Gaëtan Voyer-Perrault on my 7 Steps of Software Development story brought this song to mind, particularly the lyrics of first verse when Code Monkey is talking to his manager ‘Rob’. I also like how he asks the crowd if anyone needs any VB code written before launching into the song. I like this live performance he did of it that I found on YouTube (scroll down for video).
Check out Jonathan Coulton’s web site if you get a chance. Also, his song got picked up as the theme song for the hilarious new G4 TV show, Code Monkeys so check it out too.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Share This Article:
These icons link to social bookmarking sites where readers can share and discover new web pages.
July 20th, 2007
While the .NET String object offers a lot of functionality, there are still some things that we can add to it. In this article, we’ll look at these 3 useful string functions:
- Shorten a string with an ellipsis in the middle
- Reverse the contents of a string
- Use XOR to do simple string encryption/decryption
1. Shorten a string that contains a file path with ellipsis
It is common to see file paths shortened by having an ellipsis in the middle, like so
c:\records\data\jon...\report_xyz.pdf
If you need to implement this kind of functionality it isn’t too hard to code it yourself but you can also use a built in
.NET function to do it as well as seen here:
Function ShortenPathString(ByVal pathString As String, ByVal targetWidth As Integer, _
ByVal targetFont As Drawing.Font) As String
TextRenderer.MeasureText(pathString, targetFont, New Drawing.Size(targetWidth, 0), TextFormatFlags.PathEllipsis Or TextFormatFlags.ModifyString)
Return pathString
End Function
In this example we use the MeasureText method of the TextRenderer object to build an appropriately sized string. The path, as a string, is passed in along with the width and font so that the correct sizing can be determined. The PathEllipsis tell the routine to place the ellipsis in the middle of a validly constructed path string.
The limitation of this routine and the underlying TextRenderer method is that it only works with a properly constructed path/filename and not with other strings.
Here is a method I came up with for doing this for any string.
Function ShortenStringWithEllipsis(ByVal targetString As String, ByVal targetWidth As Integer, _
ByVal targetFont As Drawing.Font) As String
Dim ReturnString As String
Dim StringWidth As Integer = TextRenderer.MeasureText(targetString, targetFont).Width
If StringWidth <= targetWidth OrElse targetString.Length <= 10 Then
ReturnString = targetString
Else
ReturnString = String.Concat(targetString.Substring(0, (targetString.Length 2)), Chr(1), targetString.Substring((targetString.Length 2)))
Dim StringParts() As String
Do While TextRenderer.MeasureText(ReturnString, targetFont).Width > targetWidth
StringParts = Split(ReturnString, Chr(1))
StringParts(0) = StringParts(0).Substring(0, StringParts(0).Length - 1)
StringParts(1) = StringParts(1).Substring(1)
ReturnString = String.Concat(StringParts(0), Chr(1), StringParts(1))
Loop
If ReturnString.Contains(Chr(1)) Then
ReturnString = ReturnString.Replace(Chr(1), “…”)
End If
End If
Return ReturnString
End Function
In this code, we check the length of the string first and if it is OK we return the string unmodified but if it is longer we split the string in half and loop, removing 1 character from each end, until it fits. I used a ASCII character 1 to serve as a placekeeper for the ellipsis since it is unlikely to be in visible text. After the string is shortened enough the ellipsis is replaced and the short string is returned.
2. Reverse the contents of a string
This simple code example shows a quick way to reverse a string using the Array.Reverse method:
Function ReverseString(ByVal targetString As String) As String
Dim Characters() As Char = targetString.ToCharArray
Array.Reverse(Characters)
Return Characters
End Function
3. Use XOR to do simple string encryption/decryption
In this example, XOR is used to do a simple encryption/decryption of a string. The string is encrypted by using the bitwise XOR operator on every character using the contents of a mask or key string. To decrypt it, the mask is applied the same way to the encrypted string.
Function XorString(ByVal targetString As String, ByVal maskValue As String) As String
Dim Index As Integer = 0
Dim ReturnValue As String = ""
For Each CharValue As Char In targetString.ToCharArray
ReturnValue = String.Concat(ReturnValue, Chr(Asc(CharValue) Xor Asc(maskValue.Substring(Index, 1))))
Index = (Index + 1) Mod maskValue.Length
Next
Return ReturnValue
End Function
This encryption method is quite vulnerable to being broken so it should not be used for any non-trivial situation. It can be made more secure by using it in conjuction with a Vernam Cipher
You can download the sample code here: 3 String Functions Demo
If you have better or different ways of doing these functions or if you have any questions about them please feel free to leave me a comment.
Share This Article:
These icons link to social bookmarking sites where readers can share and discover new web pages.
July 19th, 2007
Next Posts
Previous Posts