The shortest, most useful program that I have ever written

When celebrities receive awards, they often express appreciation for the contributions of all the “little people” who made their success possible. While this may seem like a back-handed acknowledgement, it is probably the most  inclusive way to recognize people in the entertainment industry in which small stature and large headedness has reached pandemic proportions.

Today I am going to follow that lead, sans golden naked man statue, and give a shout out to one of my most successful “little programs.”

Introducing cmd2clip.exe

Although the details are a little fuzzy, I wrote cmd2clip and began using it around 1996 and have used it on a daily basis for over a decade. It does one very simple, but incredibly useful thing. It copies whatever is passed to it on the command line to the Windows clipboard.

Here is the original (VB) source code in all its diminutive glory:

Public Sub Main()
Clipboard.SetText Command$
End Sub

What it does

While it may not immediately seem all that useful, context is everything. This program is intended to live in the  C:\Documents and Settings\yourpofile\SendTo\ directory which adds it to the “Send To” shortcut menu in explorer that is displayed when you right-click on an object in explorer.

Cmd2Clp SendTo Menu

This provides a quick way to copy the full path to a file or directory onto the clipboard making it easy to e-mail a path to someone or insert it into a configuration file, even if it is at the end of a long path.

 The Update

In the years since I originally wrote this in VB4, I’ve only had to update it once.  In exchange for around 30 extra lines including white-space and comments, I modified the utility to provide better formatted output when selecting multiple objects or those with spaces in the path.

Public Sub Main()
'The SendTo command will pass in the following on the command line:
' -If multiple files are selected, they are space delimited
' -If there is a space in the path of a file it is enclosed in quotation marks.

Const DelimiterBetweenFilenames As String = vbCrLf

Dim FileNames As String
Dim EvalCharOffset As Long Dim EvalChar As String
Dim AreQuotesOpen As Boolean: AreQuotesOpen = False

For EvalCharOffset = 1 To Len(Command$)
EvalChar = Mid(Command$, EvalCharOffset, 1)
If EvalChar = """" Then
'Don't append quotes to output, just toggle the AreQuotesOpen status
AreQuotesOpen = Not AreQuotesOpen
If (EvalChar = " ") And (Not AreQuotesOpen) Then
'A space outside of quotes indicates the start of a new path, add a delimiter
FileNames = FileNames & DelimiterBetweenFilenames
FileNames = FileNames & EvalChar
End If
End If
Next EvalCharOffset

Clipboard.SetText FileNames
End Sub

What’s Next

Although I’d love to get the line-count back down using the pre-tokenized args parameter provided in the Main() method for both C# and VB.NET, I doubt I’ll bother updating unless I dream up some new functionality that I need that won’t drive up the complexity considerably.

The most likely candidate is to detect when the path contains a locally mapped path and convert it to its canonical format to make it more appropriate for e-mailing to someone else. For example, changing X:\myfile.xml to \\myserver\fileshare\myfile.xml.

Why I am proud of this little utility

Admittedly, this hardly qualifies as code golf, and there is absolutely no major technical accomplishment demonstrated by this widget. There is just something about the combination of brevity and utility of this app that makes me feel good about it.

I suppose it appeals to my notion that less is more, at least to the point where you start obfuscating more than simplifying. I believe that SLOC metrics should work like golf scores, the lower the better.

How about you?

I’d love to hear about your mighty-mouse apps.  Feel free to brag about them in the comments.

Download Link

By request, here is a link to download the compiled version.


Usability: Don’t Force Old Dogs to Learn New Tricks

This old dog

I learned a few tricks this week for working with one of the oldest interfaces since punch cards, the command line. More specifically, I found a few shortcuts and features of the console UI provided by Windows, also known as “The Command line”, or inaccurately as a “DOS Window.” It turned out to be one of those rare gems that you stumble on that immediately make you more efficient.

If you are interested in the trick I found that inspired this post, check out the article I wrote about it, “Windows Console Tricks and Shortcuts”.

A Deeper Understanding of Canines

Indirectly, I also learned a lesson about how extreme familiarity with an interface creates blind-spots that inhibit discovery of new features. If my experience is typical, it appears that over time users settle into an application and tend to stop looking as aggressively for ways to use it more efficiently. In fact, I would contend that there exists a tipping point in the learning curve with a user interface beyond which the idea of changing the way a user performs a task in the interface, even if it is simpler, creates anxiety and consequently resistance.

Another possible explanation for how these features are so effectively hidden in plain sight is the tendency of a user’s UI pattern memory to fade quickly when it isn’t reinforced. If a standardized technique falls into disuse, it can’t easily be resurrected to encourage users to discover features in places that used to be familiar. This is particularly evident in Raymond Chen’s recent eulogy for the obscure Windows affordance of left-click menus on system tray icons.

I’m not sure exactly what the take-away is from this epiphany except perhaps that adding new UI elements to accomplish existing tasks in a mature product  is unlikely to create many converts among veteran users.  As a corollary to that, there seems to be a discrete window of time during which it is safe to make extensive modifications to existing UI elements without stressing (e.g. pissing off) your existing user-base. Once that window has elapsed, it is probably safest to keep the old UI available and find a way to encourage new users indoctrinated on using the updated UI.

Applying the Lesson

Several years ago, I found myself on the other side of the discussion.  During my routine debriefings from the sales team, it was communicated to me that  some of our competitors were using advanced search functionality as an effective differentiator against our flagship product, a Web-based document repository for litigators. Naturally, we endeavored to close the gap in the search-UI arms race and quickly began to conceptualize an upgrade to our software.

The application had already been in use for years and had accumulated a loyal following of veteran users who could rightfully claim to be experts on it. Also, the search interface had changed very little since I originally designed and built it back when I was still bootstrapping our product development team. The search interface was simple, but functional, and more importantly the venerable UI was very familiar to the existing user-base.

Existing Search Interface

Existing Search Interface

Key issues indicated  in the user stories and requirements.

  1. Advanced Searching: Need the ability to run more complex Boolean queries like “Letters dated May 5th, or Reports from any day in 1993”
  2. More Sorting Options: Need the capability to sort on more than one field and specify the sort direction.
  3. Optimization:  Avoid querying the contents of the drop-down controls until it is clear that the user intends to use them.

The first requirement had the greatest potential to be disruptive to the familiar layout of the existing search screen. It would require significant rework to enable users to group search terms and specify an AND or OR operator. As you can see below, the new version was indeed markedly different visually.

New Search Form

New Search Form


During beta testing, existing customers were appreciative for the new capabilities, but were hesitant to accept the new screen layout. They found the new version confusing and expressed concern about the number of clicks required to do single-field searches. Some couldn’t express exactly what they didn’ t like about the new screen, they just felt uncomfortable with it. Interestingly, users unfamiliar with the old search screen did not register any complaints.

Back to the Drawing Board

Ultimately, I drew the conclusion that the problem wasn’t so much that it was a badly designed UI, although I have since reconsidered the layout, but rather that I was effectively devaluing the time investment that longtime users had made to learn how to use the software. Recognizing this, we took the following approach to keep our loyal customer-base happy, but encourage the gradual transition away from the old interface .

  • Add an updated version of the existing screen (shown below) that addressed as many requirements as possible without a major visual change.
  • Label the new screen in the UI as “Advanced” (powerful) to encourage its use.
  • Label the old screen in the UI as “Classic” (Outdated) to discourage its use.
  • Add a toggle link to enable easy switching between the screens (indicated by red arrows in the screen-shots).
  • Add a setting to allow the user to specify their default search screen.
  • Configure existing users to continue using the old screen by default.
  • Configure new users to default to the new screen.
Updated Version of Existing Search Form

Updated Version of Existing Search Form


It has been several years and many releases since the events of this story and we are still supporting the dual search interface. My plan to get everyone to switch to the new screen and silently kill off the “Classic Search” interface didn’t pan out .
It seems that although most of the new users, and quite a few of the veterans eventually transitioned to the new interface, a third class of users has emerged that likes to toggle between the screens depending on the complexity of the search they are running.
I suppose life is full of these valuable lessons, but as long as our users are content, I can’t complain.

Pop Quiz!

Consider Microsoft’s decision to scrap the most familiar group of UI elements for most Windows users, the toolbar/menu interface, and replace it with the new “Ribbon” control. Should the negative reaction it engendered have been predicted?

What do you think MS could have done differently to honor the investment of their customers in learning their “classic” interface assuming that they had valid usability research showing that the new UI was superior?

Office 2007 Ribbon. Why, Microsoft, Why?

Office 2007 Ribbon. Why, Microsoft, Why?

Selecting A Primary Programming Language

A question that I frequently see in technical forums and other places that programmers congregate asks for guidance regarding which programming language that someone just starting out in software development should learn first, or specialize in. Although it is asked in earnest by novice programmers hoping to mine the collective experience of the veterans, such subjective questions on religious issues are not likely to garner useful or consistent answers.

It’s like asking a group of people about their opinions on abortion. The issue is so polarized that you are likely to get a fairly dogmatic answer that reflects the worldview of the person answering without much context, at least not any context that integrates more than one ideological view.

How NOT to select a programming language

First, let’s get some of the WRONG reasons out of the way for choosing a language to specialize in. Almost every time this question comes up, the person asking either implies or explicitly specifies that the criteria they are most interested in are (A) earning potential; and (B) employment trends that indicate the marketability of the skill.

Don’t select a language based on earning potential

It is true there exists disparity in the average salaries of programmers based on the language they use. Aside from the ~$20K disparity for VB.NET, that I think has more to do with the baggage of the Visual Basic name than the real comparative value of those programmers, most of the popular languages are averaging within $5K/year of each other according to the numbers I found on (click image for more detail) and there have been several lead changes over the last few years.

Salary Trends by Programming Language for Austin, Texas

Salary Trends by Programming Language for Austin, Texas

It is also important to consider that salaries tend to spike for technologies as they near obsolescence because it gets harder to find candidates with experience in those technologies and are willing to risk sitting in the COBOL chair when the music stops.  I think the next major victim of this will be C++, but not for at least another decade or two.

A more important consideration is that these salary numbers are just averages and should only be used to get a general picture of the market for various skills.  In my experience, the level of experience and competence in a particular language is more deterministic on salary than the choice of language itself.

The premium for a programmer in their first job out of college in C++ might be tempting, but I have observed that discrepancies based on specific languages tend to converge over the course of a career and are much less pronounced for veteran developers.  As such, it is probably more useful to focus on mastering a language than picking the right one.

Don’t select a language based on marketability

Looking at the number of available jobs is perhaps the worst way to pick a programming language. This field changes too quickly for it to be wise to make long term decisions on short term trends. There are numerous examples of labor markets glutted with people who embarked on a career path because of a shortage was that drove up salaries when they started college. By the time those people graduate along with the 75% of their class who got the same diploma, the market once strapped for talent became excedingly competitive and consequently less desirable.

.net, java,,c#,c++,ruby,python Job Trends graph

 How to select a programming language

This is the easy part. Pick the one you like best! You are far more likely to invest the effort required to master a language that you pick by preference than one selected for purely monetary or competitive reasons. That said, the language you select shouldn’t win by default, but rather should be selected from a pool of at least 3 languages for which you have had some exposure:

  • Still in school?  Try to select courses that give you exposure to several programming languages and at least two platforms (Windows, Apple, Unix, etc.) You can hedge your bet by learning C++ which is extremely similar several other languages and will reduce your learning curve, but don’t use that as an excuse to learn just one language.
  • Early Career Programmer? At this stage of  your career, it is fairly safe to make a major platform shift when taking a new job. Employers tend to be more forgiving on lack of experience for a specific language on entry level positions if the candidate can demonstrate competency at programming in general.
  • Tenured Developer?  This is a much tougher situation. At this stage of your career, a lot of your value is often built upon experience in your primary language. Making a jump, for example from Java to C#, is likely to set you back a few notches on salary because of your relative inexperience in the specific language.

What types of projects do you want to work on?

Another factor you should be aware of, is that your choice of language is going to play a big role in the types of software development projects you will work on. The following are gross over-generalizations, but should give you a rough idea of the most common projects associated with each language:

C++:  System Programming, device drivers, computer science-y projects.
Java: Commercial Software targeted for Linux and Windows as an afterthought, Web development.
C#: Commercial software targeted exclusively to windows, Web development.
VB.NET: Internal Development, Systems Integration, Web development.
Visual Basic 6: More likely to involve commercial software development than VB.NET, but mostly maintenance work on legacy/cash-cow systems.
Ruby/Perl/Python: Scripting, Web development.

Culture Considerations

Although Hollywood  likes to lump us into broad stereo-types of nerd or hacker, depending on which way the pendulum is swinging about how hip it is to be a computer guy, we know that there is a rich diversity of subculture among us that don’t automatically co-exist peaceably.

The choice of a programming language is a lot like picking a table in the high school cafeteria. It will label you and go a long way towards determining what type of people you will have to put up with all day. I’d suggest familiarizing yourself with the culture of the language(s) you are considering through newsgroups and user groups before making a decision on a language.

Still can’t decide?

Is it all the same to you? This isn’t a good sign. If you don’t have a strong opinion about such a critical aspect of what you intend to do for a living, I’d question whether you made the right career choice to go into this business in the first place. Don’t you know there is a platform war going on out there soldier? Pick a side, get out there, and fight!

Final Thoughts

You really can’t go too horribly wrong on picking a language unless you select one on the verge of extinction. It may be slightly easier to make a little more money or find a job more quickly with some languages, but no matter which you chose, you will eventually find work and at a good wage if you invest the time to master your craft.

The bottom line is that you should follow your bliss when making any career decision. You are simply going to spend too much of the prime years of your life at work to do something you that don’t enjoy.

A Manager’s Retrospective on the C# versus VB.NET decision

There is no shortage of discussion or flame wars weighing the relative merits of the various Microsoft .NET programming languages, nor is there an outcry for another opinion on the subject. This article will instead discuss the process of making a sound business decision on a controversial issue without inciting mutiny among the developers. More importantly, I’ll revisit some of the key considerations in that decision through the razor sharp focus of hindsight. It is my hope that my experiences from the trenches will provide guidance to software development managers who have not yet made the jump to .NET, are bootstrapping a new shop, or are considering a switch from another platform.

It’s been just over six years since I managed the transition of my development team to Microsoft’s .NET platform and made the call, for better or worse, to standardize on VB.NET. As a developer myself, I was keenly aware of the how the programming language of a software development shop defines its culture and similarly shapes the professional identity of many programmers. The polemic among developers created a real risk of breaking down the team dynamic through second-guessing and deflated morale regardless of my choice. As is the case with implementing any politically sensitive change, the prudent course of action was to aggressively seek buy-in by actively soliciting input of each team member, remaining visibly objective, and maximizing the transparency of the issues that factored into the final decision. Despite the lack of unanimity requiring over 30% of the team to acquiesce on this hot-button standardization issue, the team dynamic remained strong after my final decision.

The Players

Although the list of languages that are currently supported on the .NET framework is more diverse than most would probably imagine, the options were far more limited back in 2003.

C#.NET: A hybrid of C and Java that attempted to lure defectors from the Java camp to the .NET platform. It also provides an easy transition for C++ refugees who are sick of the annoyances of manual memory management and having 9 incompatible ways to implement a simple string.

J#.NET: Most of the quirks of Java and none of the cross-platform support and about as useful as non-alcoholic beer. Enables developers to pretend they still hate Microsoft, but participate in their market share. Also allows Microsoft to pretend that C# wasn’t a blatant attempt to crush the upstart Java language that threatened to weaken their dominance of the OS market. The technology pundits have moved on to other issues enough for Microsoft to silently drop support for J# from Visual Studio.

VB.NET: The next generation of the popular Visual Basic language, all grown up and fully OOP capable. It is unfortunate that Microsoft didn’t take this opportunity to rename the language to remove the stigma associated with programmers using this language that only resembles its forebears in its verbosity. I assume they kept the name to provide an unambiguous upgrade path for the unwashed masses of VB6 programmers many of which ironically and belligerently dug in their heels and refused to upgrade.

C++.NET: For a while I assumed that I must have been missing something with respect to C++.NET. The juxtaposition of the venerable I’ll-roll-my-own-thank-you-very-much C++ and the don’t-worry-your-pretty-little-head-about-cleaning-up-that-memory .NET framework felt even more awkward than “Java.NET.” I took a course to absolve me of my silly notions, but only managed to reinforce them. C++.NET is neither fish nor fowl. It is like a halfway house for recovering masochist programmers who really want to like automated garbage collection, but want to take it one day at a time. Just one more hit of STL, I promise I’ll quit tomorrow! In one of the rare parallels with the VB camp, many of the Microsoft Visual C++ developers found little motivation to abandon Visual Studio 6.

The Contenders

Let’s face it. Aside from C#, VB.NET, and their ugly cousin C++.NET, none of the remaining .NET languages were used for much more than  Microsoft demos to prove that they wanted to support open standards. This was even truer back in 2003 when I was weighing the options. The team divided itself naturally into a C# and VB.NET camp and no one even hinted at seriously considering a third option.

The Process

It is extremely important when soliciting input from employees to be very clear about how the final decision is going to be made, especially when it is not the purely democratic process that they might otherwise assume. Recognizing this, I was careful to communicate that while everyone’s input was valued and would be carefully considered, I’d be making the final decision based on both the advice of the team and the interests of the business. I promised complete transparency on my decision and a chance to appeal it on factual, but not subjective grounds. As it happened, no such appeals were proffered. The C# proponents were slightly disappointed, but were also thankfully supportive the decision to go with VB.NET.

My solicitation for input included the following:

  • Provide as many supporting arguments for your preference as apply to our environment.
  • Arguments based on business objectives (reduced cost, greater efficiency) will be weighed more heavily.
  • Performance comparisons between the languages had been researched and dismissed already, don’t bother including them.
  • It is perfectly valid to support your preference in terms of your personal goals (money, prestige, taste, etc.).
  • Regardless of whether you can support your preference, please indicate it in your response. Morale impact is a key consideration.

Facts, Factors and Opinion

After compiling my own research, business case analysis, and the collective wisdom and opinion of my team, the following key themes emerged.

  • Functionality (TIE): Functional differences between the capabilities of these languages were primarily cosmetic/syntactic/irrelevant(Appleman/Atwood), MSDN.  There were a few IDE features that one language or the other had the edge on, but MS was already promising IDE parity in future releases.
  • Learning Curve (VB.NET): Because our previous standard was VBScript for ASP pages, and VB6 for the middle tier object layers, VB.NET seemed like the quickest path to productivity. I was particularly concerned about the impact of forcing the developers to make the jump to a completely different language at the same time they would be also required to get up to speed on the .NET framework and ASP.NET.
  • Existing Code (VB.NET): We were maintaining a significant amount of existing VB6 and VBScript code that would need to be ported to .net. Visual Studio provided tools to automate most of the conversion from to VB.NET, but considerable extra time would have been required to go to C#.
  • Product Road maps for .NET languages (VB.NET): An MSDN magazine article comparing the road maps for the two languages indicated that VB.NET was going to continue to be optimized for rapid application development while C# would follow the tradition of C++ and trend towards power-user features. The direction of VB.NET was more relevant to our development efforts which were mostly on CRUD type applications.
  • Developer Preferences (VB.NET): Despite the tendency of most to gravitate towards the familiar in platform wars, C# had a good showing. The balance was tipped by a few developers who had already started down the VB.NET track of their MCSD certifications. I hate to reinforce the stereotype, but it was interesting to note that the more senior developers were mostly in the C# camp.
  • Developer “Street Creds” (C#): Almost all of the developers subscribed at least weakly to the popular notion that C# experience would command a higher premium than VB.NET by riding the coattails of C++ as a more respected language. Whether justified or not, it appears that this rumor has become fact.
  • Product “Street Creds” (C#): There was also some concern that the “taint of VB” would hurt the perceived professionalism of our software among our customers. I have not yet seen evidence of this, however, we don’t advertise the language we use, and our customers don’t generally ask or care.
  • Recruiting (TIE C#): There was a lot of discussion that MS was strongly favoring C# as the language of choice for .NET and that most developers were following suit. I was somewhat concerned about the possibility of VB.NET becoming marginalized and creating recruiting hurdles. That is, if VB.NET became uncool, it might be difficult to get people to respond to our job postings even if we didn’t discriminate against people with only experience in other .NET languages. On the other hand, I reasoned that we might be able to avoid paying a “C# premium” that didn’t guarantee any associated additional value add over a competent VB.NET programmer. I think that predictions of VB.NET’s demise were very premature as it continues to have a solid following. However, in retrospect, I think I underestimated the impact of the decision on recruiting. I suspect that some of our recruiting difficulty (even with very competitive salaries) can be attributed to the fact that VB.NET developers readily apply to C# jobs, but the reverse is not as common.
  • Language Obsolescence (Non-factor): A small contingent was even predicting that Microsoft planned to phase out VB.NET in favor of C#. I just didn’t buy into this notion given my experience with how slowly Microsoft has retired product lines in the past. It took them 27 years, for example, to retire FoxPro after acquiring it, and salvaging it for parts to include in their competing database package, MS Access. So far it appears my skepticism was warranted.


As I have already mentioned, our team went with VB.NET. I still think it was probably the right decision given the skills of my existing team and our considerable investment in legacy code in VB based languages, despite the minor difficulties it has created for recruiting. Absent either of these preconditions, however, I definitely would suggest a preference for C# for any manager going through this decision today. That said, this article is no substitute for your own research. As is the case with any heated topic, there is an abundance of misinformation, some of which may even be repeated by members of your own team. One resource that I have come to trust over my years in this industry is Dan Appleman, who has published a highly regarded e-book, Visual Basic .NET or C#, Which to Choose? (VS2005 edition).

The lesson that can be drawn from my experience, however, is not so much about a preference of one language over the other, but instead the importance of involving the whole team in the change management process. This decision has major ramifications on their professional careers that extend beyond the walls of your organization and has the potential to create significant anxiety among them. Manage that anxiety by including them in the process, making it clear that their individual interests are being carefully considered, and the making the decision objectively and transparently as possible.

Links to the Fray