I <3 Steve McConnell*
Coding Horror
programming and human factors
by Jeff Atwood


26 posts from August 2005

August 31, 2005

Don't Make Me Think, Second Edition

A reader recently pointed out that the second edition of Don't Make Me Think is about to be released. I know I've pimped this book ad nauseam, but I can't help myself-- it's just that good. If you only read one book on usability and UI, it should be Krug's Don't Make Me Think. I even gave it to my wife to read, and she enjoyed it too. Is there any higher praise?

Don't Make Me Think, Second Edition

Unfortunately, Steve Krug's website doesn't have any information on what's new in this version. The yellow sidebar indicates "3 new chapters", but beyond that, who knows.

I'll be getting a copy of the new version for sure. I can keep the old one at home and the new one at work, or I can surprise an unsuspecting manager or fellow developer with the first edition. Now if only I could get them to read it..

Posted by Jeff Atwood    7 Comments

August 30, 2005

Usability vs. Learnability

In this 1996 Alertbox, Jakob Nielsen champions writing for the web in an inverted pyramid style:

Journalists have long adhered to the inverse approach: start the article by telling the reader the conclusion ("After long debate, the Assembly voted to increase state taxes by 10 percent"), follow by the most important supporting information, and end by giving the background. This style is known as the inverted pyramid for the simple reason that it turns the traditional pyramid style around. Inverted-pyramid writing is useful for newspapers because readers can stop at any time and will still get the most important parts of the article.

On the Web, the inverted pyramid becomes even more important since we know from several user studies that users don't scroll, so they will very frequently be left to read only the top part of an article. Very interested readers will scroll, and these few motivated souls will reach the foundation of the pyramid and get the full story in all its gory detail.

For some reason, the idea that "content should never appear below the fold because users don't scroll" was a very widely held belief well into the millennium. I don't know what user studies Mr. Neilsen is referring to; even the ancient 1998 reference Web Site Usability: A Designer's Guide found no evidence to support this claim:

The Fidelity site, more than any other site we tested, went to great lengths to have many of its pages completely above the fold. The result is lots of pages, each with small amounts of content. There was no evidence to suggest that this strategy helped or hurt.

In fact, we never saw any user frustration with scrolling. For instance, when we counted "first clicks" -- the first place people clicked when they came to a new site -- clicks were just as likely to be above the fold as they were to be below it. If scrolling below the fold was a source of frustration, we would have expected to see some sort of negative correlation between first clicks below the fold and success, but we didn't.

In 2003, Jakob added an addendum to his Alertbox, which reads:

In 1996, I said that "users don't scroll." This was true at the time: many, if not most, users only looked at the visible part of the page and rarely scrolled below the fold. The evolution of the Web has changed this conclusion. As users got more experience with scrolling pages, many of them started scrolling.

You should certainly try to put the most important information at the top of whatever it is you're writing, be it a website, a program, an email, a resume, etc. Believe me, I've learned this the hard way; you're lucky if they read anything, much less the first paragraph.

But to claim that users don't scroll is downright ridiculous, even for 1996. Let's say you had a user who didn't know how to scroll a web page. How long would it take this user, however timid they may be, to learn that they needed to scroll when browsing the web? A user who can't learn to scroll within a few hours certainly won't be using the internet for very long.

In Joel Spolsky's excellent User Interface Design for Programmers, he notes the difference between Usability and Learnability:

It takes several weeks to learn how to drive a car. For the first few hours behind the wheel, the average teenager will swerve around like crazy. They will pitch, weave, lurch, and sway. If the car has a stick shift they will stall the engine in the middle of busy intersections in a truly terrifying fashion.

If you did a usability test of cars, you would be forced to conclude that they are simply unusable.

This is a crucial distinction. When you sit somebody down in a typical usability test, you're really testing how learnable your interface is, not how usable it is. Learnability is important, but it's not everything. Learnable user interfaces may be extremely cumbersome to experienced users. If you make people walk through a fifteen-step wizard to print, people will be pleased the first time, less pleased the second time, and downright ornery by the fifth time they go through your rigamarole.

Sometimes all you care about is learnability: for example, if you expect to have only occasional users. An information kiosk at a tourist attraction is a good example; almost everybody who uses your interface will use it exactly once, so learnability is much more important than usability. But if you're creating a word processor for professional writers, well, now usability is more important.

And that's why, when you press the brakes on your car, you don't get a little dialog popping up that says "Stop now? (yes/no)."

I was greatly impressed with the expanded book version of Joel's User Interface Design for Programmers page. I sort of assumed that the book was a mildly enhanced reprint of the HTML, but 7 of the 18 chapters are completely new material. Based on a few quick Google searches, they really are new. And the full color printing is fantastic!

I've read a bunch of UI books, and Joel's is easily in my top three. I'll definitely be adding it to my recommended developer reading list.

Posted by Jeff Atwood    19 Comments

August 28, 2005

Variable "foo" and Other Programming Oddities

If you've ever viewed UNIX documentation, you've probably encountered variables foo and bar at some point. Here's a Ruby example I found in the newsgroups:

foo = 0
bar = 0
1.times do
  foo = 1
  foo := 2
  bar = foo+1
end

puts foo, bar 

O'Reilly's FooCamp ostensibly means "Friends of O'Reilly" but is probably a pun on this same meaningless variable. So why "foo"? I always thought foo and bar were corruptions of the phrase FUBAR, but according to the jargon file, that's not correct:

When ‘foo' is used in connection with ‘bar' it has generally traced to the WWII-era Army slang acronym FUBAR (‘F*cked Up Beyond All Repair' or ‘F*cked Up Beyond All Recognition'), later modified to foobar. Early versions of the Jargon File interpreted this change as a post-war bowdlerization, but it it now seems more likely that FUBAR was itself a derivative of ‘foo' perhaps influenced by German furchtbar (terrible) -- ‘foobar' may actually have been the original form.

For, it seems, the word ‘foo' itself had an immediate prewar history in comic strips and cartoons. The earliest documented uses were in the Smokey Stover comic strip published from about 1930 to about 1952. Bill Holman, the author of the strip, filled it with odd jokes and personal contrivances, including other nonsense phrases such as "Notary Sojac" and "1506 nix nix". The word "foo" frequently appeared on license plates of cars, in nonsense sayings in the background of some frames (such as "He who foos last foos best" or "Many smoke but foo men chew"), and Holman had Smokey say "Where there's foo, there's fire".

Then there are GUI widgets. I know the word predates computers as a generalized business school expression of "some unit of produced goods", eg, from ACME Corporation. But where did the word "widget" come from?

"Widget" is a deliberately invented word meant (probably) to suggest "gadget". Most dictionaries fail to trace it to its origin. It comes from the 1924 play "Beggar on Horseback", by George Kaufman and Marc Connelly. In the play, a young composer gets engaged to the daughter of a rich businessman, and the next part of the play acts out his nightmare of what his life will be like, doing pointless work in a bureaucratic big business. At one point he encounters his father-in-law at work, and we get the following dialogue:

(Father-in-law): Yes, sir! Big business!
Yes. Big business. What business are we in?
Widgets. We're in the widget business.
The widget business?
Yes, sir! I suppose I'm the biggest manufacturer in the world of overhead and underground aerial widgets.

Part of the point, of course, is that no one ever tells him what "widgets" are.

A play, of all things. It certainly must have been popular in the 1920's for this weird little word to catch on; a google search reveals a bunch of hits for recent productions of Beggar on Horseback.

The Beagle Brothers were one of my favorite Apple // software vendors. They had disks chock full of crazy little programs and demos, all written in Applesoft BASIC. In many of these apps the sentence "Pack my box with five dozen liquor jugs" appears. Just more Beagle Brothers zaniness, I thought. Years later, I realized what this phrase actually is. It's a pangram: it uses all 26 letters of the alphabet in a single sentence.

The wikipedia entry notes that pangrams are typically used in font sample apps. That's what launches in Windows when you double-click on a font in the c:\windows\fonts folder. Here are a few examples:

How razorback-jumping frogs can level six piqued gymnasts!Mac, System 7 era
Cozy lummox gives smart squid who asks for job penMac, post-System 7 era
The quick brown fox jumps over the lazy dogWindows, truetype fonts
Pack my box with five dozen liquor jugsBeagle Bros fonts
Jackdaws love my big sphinx of quartzWindows, bitmap fonts

beagle_pack_my_box.png

The pangram Beagle Bros chose is a great expression of their homebrew spirit: it's rather clever and it involves alcohol.

Posted by Jeff Atwood    10 Comments

August 27, 2005

The Rise of the PokerBots

Computer geeks have a long history of gaming the gaming industry. One of the most notable exploits is documented in the book Bringing Down The House: The Inside Story of Six MIT Students Who Took Vegas for Millions (read an excerpt in Wired). But things have changed now that gambling is moving to the internet in a big way. There's a fascinating article on Wired about the rise of the PokerBots:

For years, there has been chatter among online players about the coming poker bot infestation. WinHoldEm is turning those rumors into reality, and that is a serious problem for the online gambling business. Players come online seeking a "fair" shot - a contest against other humans, not robots. But an invasion of bots implies a fixed game (even though, like their mortal counterparts, they can and do lose if their hands are bad enough or opponents good enough). So the poker sites loudly proclaim that automated play is no big deal. At the same time, they are fighting back by quietly scanning for and eliminating suspicious accounts. "We're making sure we never have bots on our site," says PartyPoker marketing director Vikrant Bhargava.

That's an impossible promise to keep, says Ray E. Bornert II, WinHoldEm's elusive creator. He's trying to flood the online world with his bot - and make a killing in the process. Bornert offers an elaborate justification for what many view as outright cheating: Online poker is already rife with computer-assisted card sharks and - thanks to him - a growing number of outright bots. Players should get wise and arm themselves with the best bot available, which is, of course, WinHoldEm.

There's a quiet knock at the door of a hotel room in Atlanta. It's Bornert. A stocky, wide-faced 43-year-old with a neat goatee and nervous manner, he's carrying a router in a plastic bag. To demonstrate his software, he insists on meeting here in private, several miles from his office. He doesn't want anyone from the poker business to know where he is. "Our guard is constantly up," he says.

For Bornert, a former evangelical student, outsmarting the poker sites is not just a mission, it's a market. A suite of WinHoldEm programs is available for download at www.winholdem.net. For $25, you get a bare-bones setup: run-of-the-mill poker-hand analysis software. For $200, you can buy the full package: a one-year subscription to the team edition, which includes the autoplaying bot and a card-sharing module that allows multiple players to communicate during a game. Bornert won't say how many customers he has; he'll admit only that he makes a living selling WinHoldEm.

I can tell you from personal experience playing free multiplayer internet games that cheating has always been a serious problem. Game developers have to be vigilant and develop countermeasures early. If they don't, popular games rapidly degenerate into a morass of disheartened, unsure players and an unknown number of cheaters. Nothing psyches you out more than the idea that another player can switch to perfect, bot-like skills at will. Did they win because they were better than you, or because they cheated? There's just no way to know. It utterly destroys the game experience.

If people are that willing to cheat for literally nothing, with zero money at stake, imagine what lengths they'll go to when real money is involved.

That's why I tend to believe Mr. Bornert, a former evangelical student, when he compares WinHoldEm to civil disobedience:

"The reality is that the game changed the moment it moved to the Internet," Bornert says. Bots and bot-aided collusion were inevitable. Rather than seduce anyone into thinking such things didn't exist, Bornert had another notion: Put the power in the players' hands. By democratizing computer-assisted firepower, he'd make it part of the competition. "It's like football - if you don't wear a helmet and pads, you're going to get hurt," he says. "A poker bot is your equipment." And if that is considered unethical, then so be it. "I'd rather be unethical than be a victim," he says. "This is intentional civil disobedience."

Despite the protests of the online casino brass, the rise of the bots is completely inevitable. There's simply too much money at stake.

Out of curiosity, I checked out the winholdem support pages. This app is doing true GUI screen-scraping of the poker apps. That's why your poker app settings and Windows display options have to be locked down to known standards.

Of course, online casinos can (and do) fight back:

  1. Make your poker apps (these are regular .exe type apps) scan for instances of winholdem running on your local pc. Some online casinos are already doing this. There's a countermeasure for that, too: run it on a remote computer with an application that transmits screenshots of the poker app to the remote machine.
  2. Periodically strike up a conversation with the "player." That's tougher to combat. You could possibly re-broadcast your chat messages to IM services, if you happen to be near a computer at the time. The bots should limit their play at any given table to prevent a lot of conversation. And definitely have a vast library of canned phrases to respond with-- maybe even an Eliza implementation.
  3. Change the UI every hand. This is the one option that I didn't see explored in the article, but would be the hardest to combat. If the cards vary in size, color, design, and position every hand-- the scraping app is hosed.

In the meantime, if anyone is making a killing on internet poker with their 'bot, more power to you.

Posted by Jeff Atwood    23 Comments

August 26, 2005

How to be Lazy, Dumb, and Successful

Philipp Lenssen agrees that inspired laziness is a desirable trait for software developers:

.. only lazy programmers will want to write the kind of tools that might replace them in the end. Only a lazy programmer will avoid writing monotonous, repetitive code. The tools and processes inspired by laziness speed up production.

But Philipp adds one caveat: truly great programmers aren't just lazy. They're dumb, too:

Programmers who know they are smart

a) stop learning
b) stop being critical towards their own work

In the endless battle between programmer and compiler, give up early and admit that it's always you and never the compiler who is at fault.

Nobody is really smart enough to program computers. The only way you'll ever succeed as a software developer is through humility and the Zen concept of beginner's mind: approaching everything as if you were seeing it for the first time. Most of all, that means not being afraid to ask the stupid questions:

.. when confronted with a problem from management, a good programmer will adopt the mindset of being dumb. He will start asking the most simple, child-like questions, because he doesn't accept the parameters someone thinks make up the problem.

Unfortunately, I frequently see developers who are afraid to ask basic questions for fear of looking stupid. Maybe it's our macho smarter-than-thou programming culture. Having the guts to ask basic questions is, ironically enough, a hallmark of the best developers I've ever worked with.

Being lazy and dumb isn't just good career advice: it's the key to running a successful software business, too. As Mark Cuban points out, everyone else is just as lazy and dumb as you are:

It was Aaron Spelling I believe who said that "TV is the path of least resistance from complete boredom". Which is another way of saying that it's easier to watch TV than it is to sit there and do nothing.

Which describes exactly how people make most of their choices in life. They take the easy way. They take the path of least resistance.

There are certain things in life we all have to do. There are certain things in life we choose to do. Then there is everything else. The things we do to kill time. In every case, all things being equal, we choose the path of least resistance.

Understanding this concept is key to making good business decisions.

In other words, the only way to build great software is to make things as easy as possible for your users.

Posted by Jeff Atwood    9 Comments

August 25, 2005

Mavis Beacon Ate My Brain!

You may be familiar with the classic Mavis Beacon Teaches Typing* series of software from Broderbund.

Mavis Beacon Teaches Typing... and the perils of late 80s office fashions.

Well, Sega's sublime Typing of the Dead is like Mavis Beacon Teaches Typing ... if Mavis Beacon was a flesh-eating zombie!!

Typing of The Dead. TYPE OR DIE!

Any self-respecting software developer should be a decent typist. Now you can prove how much of a keyboard ninja you really are, because here's the best part: Typing of The Dead supports 2-player competitive network play over TCP/IP, with comprehensive post-game stat tracking (see screenshot).

It's hard to explain just how wondrously bizarre Typing of the Dead is. It's a challenging, remarkably well thought out typing tutor, a tongue-in-cheek b-grade zombie movie, and the most hilarious multiplayer game experience you'll probably ever have-- all at the same time.

As a zombie enthusiast, I bought Typing of the Dead immediately after it was released in 2001, but I can't find any vendors currently selling the PC version of the game on Froogle or eBay. It may legitimately be abandonware and therefore downloadable as a torrent ISO from The Underdogs. Once you obtain the game, legally or otherwise, install the nocd patch from GameCopyWorld, then copy the ~560mb install folder to a network share. Here's how to get a network game going:

  • Copy the game to your hard drive
  • Obtain and write down IP address of host (you'll be prompted for this later)
  • Run game, select Network menu option
  • One person selects Host Session, the other person selects Join Session and types in the IP of the Host
  • Important: if either computer is using Windows Firewall, you must ALT+TAB to desktop, check for Windows Firewall block dialogs, and unblock the game.

Now sit back and watch the hilarity ensue. It's pure genius.

In my testing, network play works flawlessly using current Windows XP SP2 systems as long as you use the original version of the game. Whatever you do, don't install the "ATI patch" for the game, as it completely breaks the network multiplayer functionality!

* Interestingly, Mavis Beacon isn't a real person. She's a logotype persona: an imaginary identity created entirely for the purpose of marketing. So I guess that puts her somewhere in between, say, Peter Norton and Carmen Sandiego.

Posted by Jeff Atwood    29 Comments

August 24, 2005

The User Interface Is The Application

Shawn Burke's post Shippin' Ain't Easy (but somebody gotta do it) explains why you have to resist change at the end of a project, no matter how justifiable and rational the reasons may be. Even the smallest change has a real risk of introducing additional bugs. The first commenter quipped:

TeX doesn't have bugs... Perhaps that's the exception that proves the rule :-)

Ian Ringrose immediately replied:

But does it have any users? Is the fact that it's very hard to use not a bug in and of itself?

Touch.

Yukihiro Matsumoto, the creator of Ruby, has strong feelings on this subject:

If you have a good interface on your system, and a budget of money and time, you can work on your system. If your system has bugs or is too slow, you can improve it. But if your system has a bad interface, you basically have nothing. It won't matter if it is a work of the highest craftsmanship on the inside. If your system has a bad interface, no one will use it. So the interface or surface of the system, whether to users or other machines, is very important.

It's also something Joel calls the iceberg secret:

I learned this lesson as a consultant, when I did a demo of a major web-based project for a client's executive team. The project was almost 100% code complete. We were still waiting for the graphic designer to choose fonts and colors and draw the cool 3-D tabs. In the meantime, we just used plain fonts and black and white, there was a bunch of ugly wasted space on the screen, basically it didn't look very good at all. But 100% of the functionality was there and was doing some pretty amazing stuff.

What happened during the demo? The clients spent the entire meeting griping about the graphical appearance of the screen. They weren't even talking about the UI. Just the graphical appearance. "It just doesn't look slick," complained their project manager. That's all they could think about. We couldn't get them to think about the actual functionality. Obviously fixing the graphic design took about one day. It was almost as if they thought they had hired painters.

I had this exact experience on a project recently. We're building all this cool back-end stuff, natch, and we needed a quickie front-end demo app to show it off. So we built a relatively simple demo app. It's decent, but barely competitive with other companies websites.

Guess what the client thought of our project?

I don't care how many kick-ass Visio architecture diagrams you have; as far as the user is concerned, the UI is the application. I know UI is Hard, but you have to build an impressive UI if you want to be taken seriously. Give your UI the high priority it deserves.

Posted by Jeff Atwood    19 Comments

August 23, 2005

Microsoft LogParser

Ask yourself this question: what if everything could be queried with SQL? Microsoft's LogParser does just that. It lets you slice and dice a variety of log file types using a common SQL-like syntax. It's an incredibly powerful concept, and the LogParser implementation doesn't disappoint. This architecture diagram from the LogParser documentation explains it better than I could:

logparser_architecture.gif

The excellent forensic IIS log exploration with LogParser article is a good starting point for sample LogParser IIS log queries. Note that I am summarizing just the SQL clauses; I typically output to the console, so the actual, complete commandline would be

logparser "(sql clause)" -rtp:-1

Top 10 items retrieved:

SELECT TOP 10 cs-uri-stem as Url, COUNT(cs-uri-stem) AS Hits
FROM ex*.log 
GROUP BY cs-uri-stem 
ORDER BY Hits DESC

Top 10 slowest items:

SELECT TOP 10 cs-uri-stem AS Url, MIN(time-taken) as [Min], 
AVG(time-taken) AS [Avg], max(time-taken) AS [Max], 
count(time-taken) AS Hits 
FROM ex*.log 
WHERE time-taken < 120000 
GROUP BY Url 
ORDER BY [Avg] DESC

All Unique Urls retrieved:

SELECT DISTINCT TO_LOWERCASE(cs-uri-stem) AS Url, Count(*) AS Hits 
FROM ex*.log 
WHERE sc-status=200 
GROUP BY Url 
ORDER BY Url

HTTP errors per hour:

SELECT date, QUANTIZE(time, 3600) AS Hour, 
sc-status AS Status, COUNT(*) AS Errors 
FROM ex*.log 
WHERE (sc-status >= 400) 
GROUP BY date, hour, sc-status 
HAVING (Errors > 25) 
ORDER BY Errors DESC

HTTP errors ordered by Url and Status:

SELECT cs-uri-stem AS Url, sc-status AS Status, COUNT(*) AS Errors
FROM ex*.log 
WHERE (sc-status >= 400) 
GROUP BY Url, Status 
ORDER BY Errors DESC

Win32 error codes by total and page:

SELECT cs-uri-stem AS Url, 
WIN32_ERROR_DESCRIPTION(sc-win32-status) AS Error, Count(*) AS Total
FROM ex*.log 
WHERE (sc-win32-status > 0) 
GROUP BY Url, Error 
ORDER BY Total DESC

HTTP methods (GET, POST, etc) used per Url:

SELECT cs-uri-stem AS Url, cs-method AS Method, 
Count(*) AS Total 
FROM ex*.log 
WHERE (sc-status < 400 or sc-status >= 500)
GROUP BY Url, Method
ORDER BY Url, Method

Bytes sent from the server:

SELECT cs-uri-stem AS Url, Count(*) AS Hits, 
AVG(sc-bytes) AS Avg, Max(sc-bytes) AS Max, 
Min(sc-bytes) AS Min, Sum(sc-bytes) AS TotalBytes 
FROM ex*.log 
GROUP BY cs-uri-stem 
HAVING (Hits > 100) ORDER BY [Avg] DESC

Bytes sent from the client:

SELECT cs-uri-stem AS Url, Count(*) AS Hits, 
AVG(cs-bytes) AS Avg, Max(cs-bytes) AS Max, 
Min(cs-bytes) AS Min, Sum(cs-bytes) AS TotalBytes 
FROM ex*.log 
GROUP BY Url 
HAVING (Hits > 100) 
ORDER BY [Avg] DESC

There's an entire book about LogParser, and Mike Gunderloy even started an unofficial LogParser fansite.

Here are a few other articles I found that touch on different aspects of LogParser:

Although LogParser is 96.44% awesome, there are a few things that I didn't like about it:

  1. I really, really need a standard deviation function. Min, Max, and Avg are nice but totally inadequate for determining how variable something is.
  2. The graphing output is cool-- but it's also a MS Office dependency. If you try to graph something on a machine without Office installed, you'll get an error.
  3. The automatic detection of column types in CSV files isn't always reliable. This meant I couldn't graph some numeric values in my PerfMon dumps because LogParser decided they were strings. I couldn't find any way to force a column to be detected as a certain type, either.

Of course, the idea of SQL being used to query a bunch of stuff isn't exactly a new one; Microsoft's WQL (WMI Query Language) is similar but more annoying and less powerful. And you'll get tons of hits if you logically extend this concept to querying HTML, too. Just try searching Google for Web Query Language.

Posted by Jeff Atwood    19 Comments

August 22, 2005

Is DoEvents Evil, Revisited

A colleague of mine had some excellent comments on the surprising reentrancy issues you'll run into when using Application.DoEvents():

The Application.DoEvents method is often used to allow applications to repaint while some longer task is taking place. This is usually the result of polling instead of using events / delegates. That's fine, but developers need to understand DoEvents processes all of the messages in the message queue, not just paint messages. This can lead to unexpected reentrancy issues. A simple example is shown below.

// some data we care about
private int _count;

// the click handler for a button
private void buttonUserAction_Click(object sender, System.EventArgs e)
{
  _count++;

  // _count won't always be 1; it depends how many times
  // this method was reentered during the DoEvents calls
  Console.WriteLine(_count);

  // simulate longer tasks that we are polling the status on.
  // call DoEvents to allows the window to repaint
  for (int i=0; i < 100000; i++)
    Application.DoEvents();

  _count--;
}

In this example, it doesn't matter if the method is reentered. But it might in other methods or applications. Always remember that DoEvents can cause methods to be reentered. And understand which methods are affected: any method that is called directly or indirectly in response to processing messages in the message queue.

It would be useful if the Form object had a Busy property; the form would only process paint related messages and skip input related messages like menus, clicks, keyboard, etc.

I put together a VS.NET 2003 winforms solution (6kb) demonstrating the code sample above.

This may make you wonder: Is DoEvents Evil?

I think it's definitely the lesser of two evils: it's either this simplified cooperative yielding or full-bore multithreaded code. DoEvents can be a big win with minimal effort in the right situations. For example, how about using it to improve perceived form load performance?

Posted by Jeff Atwood    12 Comments

August 21, 2005

Clean Sources Plus

Omar Shahine's Clean Sources is a nifty little right-click app for .NET developers:

This application does one thing. It adds an explorer shell menu to folders that when selected will recursively delete the contents of the bin, obj and setup folders. If you have a .NET project that you wish to share with someone, this is useful to remove the unnecessary stuff from the folder before you zip it up and send it off.

There's one glaring omission here, though. The source control bindings aren't removed! And neither are the local user setting files. I finally had some time, so...

Presenting Clean Sources Plus. It adds a right-click menu to folders that does the following:

  • Removes bin, obj, Debug and Release folders
  • Removes source control bindings from project and solution files
  • Removes user setting files

The result is a very clean, minimal set of .NET solution files, suitable for upload or sharing.

Updated to version 1.1 on 11/10/05 with the following new features:

  • Added second context menu "Clean and Zip Sources" which also zips the entire folder contents into a single zip file. This zip file is placed in the root folder and shares the same name as the folder.
  • The regex patterns used to determine what files and folders to delete are now set in the .config file. This way you can customize what gets deleted without recompiling.

I tested this with both C# and VB projects, but I'm not 100% sure it works for all other types of projects. It shouldn't break anything, but I may have missed some oddball project type (database? setup?) source bindings. And I only tested against the typical SourceSafe bindings. Anyway, test it out and let me know if there are any issues.*

* If this app deletes all your source code, then it's Omar's fault.

Posted by Jeff Atwood    31 Comments
Read older entries »
Content (c) 2009 Jeff Atwood. Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved.