2D Head with a clock as an eyeball.
 Friday, July 06, 2007

Inspired by this recent post about types of programmers, I found myself asking this question:

If you could have databases of information uploaded to your brain, which three would you pick?

I think I'd like to have Google Maps, MSDN and Wikipedia.


Filed under:  | 
 Tuesday, July 03, 2007

Jason recently wrote about ‘building your own’ Vs ‘buying a prebuilt’ PC.

Hot custom 67 by Don Borth.

"I have stopped operating my personal business and now I pay retail for all my hardware instead of going to wholesalers. I have also stopped building my own PCs and my last three purchases have been big name, off the shelf computers. It just isn't worth my time anymore to save a few bucks wherever I can."

I suppose there is a damn good reason why the big names in PC building became big in the first place: They take the pain out of buying and owning a PC. As a fellow system builder from eons ago, I found that two things drove me away from doing it on a grand scale. Firstly, you can’t compete against the 24 hour after sales support of the bigger manufacturers. Secondly, as Jason points out, you are inevitably forced to mix business with friends. I’ve got to admit that it was mainly the former that made it hard, the latter added insult to injury. Because I have chosen not to make a career out of supporting hardware, it is only natural for me to tell friends and family to go and see somebody who is more equipped to deal with their computing needs. I simply am not a hardware support specialist. The story changes dramatically if they would like some advice regarding software decisions (and so does the quote

It’s clear that recommending your friends to go and pick up a cheap PC from Joe’s electronic emporium is tantamount to ending a friendship, but even if Jeff & Scott started building PC’s fulltime for a living I’d probably still build my own.

I still build my own PC's because I'm prepared to take the time to research the combinations (which isn’t all that much) and I'm also prepared to provide myself with the '24 hour after sales support'. If I have a warranty issue, I’m prepared to wait a little longer to get my new part; I have more than one PC anyway. The benefit is that I get to spend more on the areas of the PC that interest me and choose from the widest set of options available. The potential savings, I feel, are a small bonus, perhaps enough to cover my time doing a bit of research on a weekend.

Perhaps the omega geek driven sense of pride of owning my very own DIY desktop scorcher has plunged me into the depths of insanity, but I have come to the conclusion that you can build your own cheap PC and keep it a secret from your friends.


Filed under:
 Friday, June 29, 2007

The topic is well beaten, and often gets revisited. Jeff Atwood & Scott Hanselman have both posted on the issue of learning and programming. It's a big issue because it is the heart of why there are so many people out there who think they can program, but clearly can't. For a few years now I've been harbouring a solution that I think could work.

The problem is that most University degrees teach you very little about the craft of programming in the business context. The other issue is that, the great programmers have 10 years experience before they hit 21.

So here is my crazy idea. Instead of hiring wannabe's fresh out of university, with 0 years experience, why not scout the keen and interested talent from high schools and provide 2-3 year apprenticeships to kids who want to get into the programming game ASAP? Sit your newbie alongside your best programmers and let them soak up the goodness. Start practicing paired programming after a while. I think it's the perfect environment to learn, while being a productive member of the team.

Perhaps the real reason why we as an industry find it hard to get good talent is because we expect the rest of the world to nurture it for us. So many other skills based industries have recognized this as the way ahead; the trades, sales, marketing and so forth. They have seen growth in their talent pool, whereas the IT industry seems to be struggling.

Could it work?


Filed under:
 Thursday, June 28, 2007

Depending on who you ask, I am either unfortunate or lucky enough to spend a significant portion of my working life at home, coding by myself. For one to two days out of each week I break away from the team environs and 'go it alone.'

Now I've never really had a problem with the idea, I grew up in a family that was supported by a family business of one. However recent posts by Jeff Atwood et al, have put a slight negative spin on things.

"Working alone is a temptation for many desperate software developers who feel trapped, surrounded by incompetence and mismanagement in the desert of the real. Working alone means complete control over a software project, wielding ultimate power over every decision. But working on a software project all by yourself, instead of being empowering, is paradoxically debilitating. It's a shifting mirage that offers the tantalizing promise of relief, while somehow leaving you thirstier and weaker than you started. "

I must admit to keeping in touch with reality by way of blogs and IM with colleagues, but when I'm at home, I'm the guy. I know the spirit of the comment is intended to strike at the heart of the one man shop, however I can't help but apply these statements to my own situation.

Personally, I think there is a balance to be found in all things. I don't think that the notion of working alone is this black and white. The distinction that needs to be made here is that there is a significant difference to being a one man shop and working by oneself. I find that, given the correct level of discipline, one can achieve more on certain types of work when you are by yourself. Provided you have a good team to return to when you are done.

Trudge work is the best kind of work to do by yourself, those menial tasks that nobody else is really interested in. Office banter and the like can really distract one from the jobs we hate to do, so doing them alone is often more productive. On the other hand, design decisions are best solved as a team.

So where is the balance? I honestly think that having the opportunity to 'knuckle down' on a new feature or a bug list for a few days, and come back to the team for a bit of review, has real merit. I think most open source development is done in this manner.

Thoughts?


Filed under:
 Tuesday, June 26, 2007

I recently posted on the evils of Microsoft.VisualBasic.MsgBox and have been looking at ways of preventing future problems to do with it. I decided on using static analysis to warn developers that they are using MsgBox rather than MessageBox.Show, so I thought I would share how I went about it.

Writing custom FxCop rules is reasonably well documented, and there are some excellent resources available for the inexperienced and experienced FxCop developer alike:

Of course the rules available in Team System and later versions of FxCop are written in .NET and therefore are very instructive to reflect using something like Reflector. However the process for writing rules can be summed up as such.

   1.   Decide if you are targeting FxCop or VS Team System Code analysis. Because they run different versions, you will have to compile your rules against the appropriate dll's. The good news is that development is largely the same from here on in.

   2.   Create a new class library project in Visual Studio and reference the FxCopSdk.dll and the Microsoft.Cci.dll. You will find these in your FxCop installation directory or in the case of VSTS you will find them in [VSInstallDir]\Team Tools\Static Analysis Tools\FxCop\.

   3.   Write your rule such that it inherits from Microsoft.FxCop.Sdk.Introspection.BaseIntrospectionRule. You may find it useful to create your own base rule class as I did:

      using System;
      using Microsoft.FxCop.Sdk.Introspection;

      namespace Nervoustych.CodeAnalysis
      {
         [CLSCompliant(false)]
         public abstract class BaseStaticAnalysisRule : BaseIntrospectionRule
         {
            protected BaseStaticAnalysisRule(string name) : 
               base(name, "Nervoustych.CodeAnalysis.Rules.Rules"
               typeof(BaseStaticAnalysisRule).Assembly)
            {

            }

            //other base class methods here
         }
      }

    Note the string literal parameter in the constructor; it refers to an embedded XML File resource that describes the rule to the FxCop engine. David Kean has a top example of a base rule class on his site.

   4.   Create the aforementioned XML file and embed it as a resource in your project. The rules document uses a schema called FxCopReport.xsd which is in the Xml directory under the FxCop 1.35 installdir. Here is an example of a Rules.xml file containing one rule.

   <?xml version="1.0" encoding="utf-8" ?> 
   <Rules FriendlyName="Nervoustych Rules"> 
      <Rule TypeName="DoNotUseMsgBox" Category="Nervoustych.Design" CheckId="NT0001"> 
         <Name>Full name of rule</Name
         <Description>Rule description</Description
         <Resolution Name="DoNotUseMsgBox">Resolution Description</Resolution
         <FixCategories>NonBreaking</FixCategories>
         <MessageLevel Certainty="99">Warning</MessageLevel
         <Email></Email
         <Url></Url
         <Owner></Owner
      
</Rule
   </Rules>

   5.   Write the rule. In my rule I wanted to warn developers of uses of MsgBox, so I needed to check any method calls for MsgBox:

   using System;
   using Microsoft.Cci; 
   using Microsoft.FxCop.Sdk; 
   using Microsoft.FxCop.Sdk.Introspection; 

   namespace Nervoustych.CodeAnalysis.Rules 
   { 
      class DoNotUseMsgBox : BaseStaticAnalysisRule 
      { 
         public DoNotUseMsgBox() : base("DoNotUseMsgBox") { } 
         public override ProblemCollection Check(Member member) 
         { 
            Method lMethod = member as Method; 
            if (lMethod == null) return base.Check(member); 
            foreach (Instruction i in lMethod.Instructions) 
            { 
               if (IsMethodCall(i) 
                  && ((Method)i.Value).FullName.Contains("Microsoft.VisualBasic.MsgBox")) 
               { 
                  Problems.Add(new Problem(GetNamedResolution("DoNotUseMsgBox"),
                     i.SourceContext)); 
               } 
            } 
            return Problems; 
         } 

         private static bool IsMethodCall(Instruction instruction) 
         { 
            if (instruction == null
               throw new ArgumentNullException("instruction"); 
            switch (instruction.OpCode) 
            { 
               case OpCode.Callvirt: 
               case OpCode.Call: 
               case OpCode.Calli: 
                  return true
               default
                  return false
            } 
         } 
      } 
   }

As you can see the override to the Check method cycles through each instruction in a method and checks its operation code, to confirm if it's a method call to Microsoft.VisualBasic. MsgBox or not. If it is, then a problem is added to the collection using BaseIntrospectionRule.GetNamedResolution. If anyone could let me know a better way to do this so that I don't have to use a string literal, I would be forever grateful.

   6.   Build your rules project and copy the resultant assembly to either [VSInstallDir]\Team Tools\Static Analysis Tools\FxCop\Rules or [FxCopInstallDir]\Rules depending on your target platform. FxCop will pick up rule assemblies from this directory. At this point you are ready to start using your custom rule against target assembliles using either the FxCop command line, GUI or VSTS code analysis.

   7.   Didn't quite work? If you need to debug your rule, then you will probably want to read this.

    All in all, it's not really that hard, the worst part is learning your way around the undocumented introspection engine. However reflecting the existing rules really helps, and there is a thriving community of mentors to reach out to if the going gets tough. Happy rule making.


    Filed under:  |  | 

    The evidence is clear….running as administrator is dangerous to your sanity. For starters it's addictive, and an entire industry has been generated from this addiction.

    As far as I can tell there are a few reasons why most Windows users insist on running as an administrator.

    • I want to install 'stuff'.
    • I need to move files around in the root directory.
    • My favourite software informs me I have to run as Administrator in order to use it.
    • I don't care.

    If you have any other reasons why you absolutely have to run as an administrator all day long, 7 days a week, I'd be happy to hear it. I think these reasons are the sign of a misinformed user.

    The real issue is that the IT industry has preferred to sell band aid solutions (i.e. antivirus software) rather than educating our customers properly. It's our own fault, a hell of our own design, and its time to demand better. There is a good reason why Linux and Mac have few issues in this department, and it's not because virus writers don't care enough to write viruses for those platforms. It's because the Linux based platforms make themselves hard targets. Vista dropped the ball, and should have made limited accounts the standard. UAC often gets turned off by users who hate message boxes.

    It's really quite simple; if the software you want demands to run as an Administrator at all times after installation, choose different software. Good software won't make such demands on the average user and just simply work. Microsoft has software certifications that demand this of 3rd party vendors, so encourage users to look out for it.

    I want to install 'stuff'

    Sure, after deciding that the latest toolbar from SuperHappy Technologies Inc. is the right toolbar for you, you want to install it. When you're done installing it for all users, create yourself a standard account and log into it. Even better, resist the temptation to install miscellaneous things in the first place. I know it's like collecting handbags or shoes, but you really don't need them. Investigate your installs, a quick Google will often tell you if the SuperHappy Toolbar is in fact ad ware. You don't need to install it to find out.

    I need to move files around in the root directory

    You do? Are you sure? Are you certain that MyResume.docx is better off in C:\Program Files\Resumes\ rather than MyDocs\Resumes\? OK, then go right ahead and log into your administrator account, and when you're done, log back into your standard account. Even better, avoid the temptation to have a 'DIY' file system structure. Make your home directory your castle, and save yourself a world of pain trying to remember which of the 5 resumes directories you created contains your current one. You will also save yourself time when you hit the file system with a search if you can restrict it to a total search area of a few gigs instead of a few hundred.

    My favourite software informs me I have to run as Administrator in order to use it

    Installation is one thing, but if that new game you bought demands to be an Administrator the whole time you are playing then get a different game. It is poorly designed. Really, software needs a damn good reason to run as an admin all the time. It just so happens that programs that demand that they do are also the prime target of virus writers. That naïve, innocent software you've installed can and often will be twisted to the whim of the h4x0rs.

    I don't care

    Too hard? Don't care? Well, you can have the 2396% hard drive performance hit that Norton's Anti Virus will provide you while cleaning up after your spy ware installs. Not to mention the $100 a year subscription for updates, and the bandwidth to download them. I prefer to not own anti virus software, and reap the benefits. When you get right down to it, the nastiest of viruses, will eat AV software alive anyway. The best antivirus program is your brain, and through care and research you can live a virus free life.

    Average users can get away with basic anti virus software that is scheduled to run overnight provided they don't browse the internet and read their emails as an administrator. They can safely turn off the auto protection features, which is the main culprit when it comes to performance decrease.

    Just remember the old adage: a little bit of pain today instead of a whole world of pain tomorrow.


    Filed under:
     Thursday, June 21, 2007

    Well, I bumped into an interesting build error this afternoon, one I hadn't seen before:

    Could not find file 'Microsoft.Windows.CommonLanguageRuntime version=2.0.50727.0'

    For reasons I shan't go into here I write production code in VB .NET, however for unit tests I write in C#. This obviously results in mixed language solutions. The error occurs when I reference a VB windows app project in my C# test project using a project reference. This windows project is also published via ClickOnce. According to this knowledge base article the solution is quite simple: use a file reference. Obviously, as I found out, this issue is not restricted to VB projects referencing VB projects; C# projects that reference VB projects are at risk too.

    The word out on the street is that you can also work around this by turning off ClickOnce security settings on the project being referenced, which wasn't an option for me. It's important to note that this issue is not intended behaviour, and we can expect a fix in the next version of Visual Studio, codename Orcas.

    I'll admit that project references can be problematic, although for the most part they work well at my workplace, but be wary if you are project referencing ClickOnce apps, and don't think you are completely immune if you use C# either.


    Filed under:  | 

    This may not be news to some of you, and for you I apologize. For the rest, please avoid using MsgBox in VB .NET projects, and use MessageBox.Show instead.

    MsgBox is a wrapper around the MessageBox.Show method and is meant for backwards compatibility with older VB projects. It should be left for those who really can't do without it.

    A common misuse for message boxes is debugging code, and most people have invariably found the following code snippet lazing about in production code from time to time:

       Try
          'Some error prone code
       Catch ex as SomeException
          MsgBox(ex)
       End Try

    The problem with this 'debugging' code is that in certain circumstances it will cause bugs of its own. Beware of MsgBox throwing exceptions. I'm not referring to just the documented InvalidOperationExceptions either. If the exception does something interesting in its overload of ToString, or if the MsgBox function fails when determining the title of the message box then anything from StackOverFlowExceptions to OutOfMemoryExceptions can occur.

    But wait…..there's more, another issue is localisation. If you are using FxCop and have turned on System.Globalization, any call to MessageBox.Show must specify the RTL nature of the box to be shown. The problem with MsgBox is that while it does some fancy work to determine the title, it doesn't bother determining the RTL nature of the parent window. The CA rule doesn't appear to have been written to take calls to MsgBox into consideration. In short, calls to MsgBox break the Globalisation rule CA1300.


    Filed under:  |  |  | 

    In my previous post I described how using some readily available tools and some simple conventions for work item creation can equip yourself with some excellent information about how your team works. In this post I intend to explore some of the custom queries that I have been asked to create in day to day life as a TFS consumer.

    One such request was for a query that will tell you, of all the work items you have delegated to others, which ones are outstanding. To achieve this follow these steps to create a TFS query. Having done that you will want to provide the following filters:

    • Team Project = @Project
    • AND Created By = @Me
    • AND Assigned To <> @Me
    • AND State = Active
    • AND Area Path Under <AreaPath>
    • AND Iteration Path Under <IterationPath>

    By changing the "AND State = Active" to be "AND State <> Active" one could query the completed and closed tasks. Optionally you could filter out Scenarios using the 'Work Item Type' field. Don't forget that team explorer can easily dump into and out of Excel which can be handy if you need an earbashing list. The query options straight out of the box are 'good enough' for most situations, and you don't have to write any code if that's not your thing.

    For those of you wanting a little more than a simple query, e.g. you want parameterisation, I did find that creating your own TFS reports was a reasonably straight forward experience as well. The first thing to do is to create a report model on the TFS warehouse objects (TfsReportDS and TfsOlapReportDS by default). TfsOlapReportDS points to a SQL Analysis Services cube which the standard reports all use. One can spend more than a few hours just looking around in there, so consider yourself warned ;)

    Creating the report model is easy enough, just browse to your TFS Sharepoint portal, and find the link to your Report server web interface (typically http://TFSServerName/Reports) and click on the TfsOlapReportDS of TfsReportDS link (the docs say you should favour the TfsOlapReportDS for reporting). Once there you can hit the generate model button and have it generate a reporting model for you. Then just click the link to report builder and start going nuts. I whipped up a non-parameterised report in under an hour that distilled the check-in history of an Area to look like an activity report, using all the wonderful comments our team had provided on each check-in, as a result of the check in policy.

    A quick TFS Report based on the TFS warehouse.

    As you can see I pulled in the change set details, the number of lines changed. Using a quick function on the max and min check in date would show how long the entire project took at a glance. Obvious improvements to this would be grouping by scenario and iteration. This report was brought to you courtesy of the Code Churn entity, which is useful for more than just this simple activity report. You can use code churn to ascertain the quality of your code as well.

    By using the report designer in Visual Studio, you can start leveraging your SQL skills (of which I have very little) to create more elaborate reports, although I think I shall leave that as an exercise for the reader, rather than going into it here as the principle is largely the same. For further information on using the report services I can highly recommend Bob Meyers SQL Reporting Services blog and a book by Paul Turley, Todd Bryant, James Counihan, Dave DuVarney entitled Professional SQL Server 2005 Reporting Services for those who don't mind reading after a hard days coding.

    In summary, developers often concentrate on making sure that each line they write is well crafted, and that's a good thing, so why not make check in time another opportunity to be efficient and useful instead of an inconvenience? There are benefits for developers and project leaders alike, and the key to finding those benefits is by having good data collected at check in time. The analysis tools provided by TFS are powerful enough to satisfy most needs, and if a SQL neophyte like me can whip up a semi-useful report in an hour, imagine what a SQL Jedi could achieve?


     Wednesday, June 20, 2007

    In a previous post I described some of the simple things we have used at work to improve our TFS life as developers, and today I thought I would share some finer detail.

    One of the single greatest tools I use to combat TFS weariness today is this fantastic outlook add-in by the SRL Team. It has changed the way our company works with TFS, I highly recommend installing it. In short you can create work items (tasks, bugs etc) from outlook items (emails, tasks etc) and also search TFS by keyword or ID.

    Another tool of note, which aids those who need to access TFS reports and source on the run, is TeamPlain, which I use at home quite a lot. This gem provides a much better web interface for developers than the standard portal TFS currently provides. Whilst you can't do bulk checkouts very easily, simple one file check-ins/outs are quite doable. I find it particularly useful for creating work items and running reports when I don't have intranet access to work. It's so good, that Microsoft actually bought the company who created it, and is now a free download. Please note, this doesn't suddenly earn you a portal for non licensed developers – you will still need CAL's for users on TeamPlain.

    The TFS Administration Power Tool is the only way to fly when you need to setup permissions for new TFS users in a hurry. It streamlines the task of setting up permissions for TFS, Share point and reporting services in one place. Perhaps its greatest feature that puts it over the line for hard core command line users is that you can easily make multiple changes at once. It also displays the activity log for all changes made, in case you need to blame somebody else for some poorly configured permissions. ;)

    Lastly, but certainly not least, if you haven't already downloaded it, then do yourself the favour of getting the TFS Power Tools. For starters tftp.exe has some excellent command line functionality for managing all manner of day to day TFS tasks; tree clean, undo unchanged, to name but a few. There is a myriad of commands and it is very easy to pickup. Along with tftp.exe there is the check in policy pack which has some fairly common check in policy examples for you to utilise. If you want to implement your own custom check-in policies, it isn't hard and I suggest you have a look at Marcel de Vries primer on the topic.

    On the topic of check in policy, we recently added one more to our front line against bad check-ins: for VB projects option strict must be turned on. <Cue-sniggers-from-the-C#-crowd/> I think it's imperative that any serious VB development be done with Option Strict on (and Option Explicit, but luckily the power of defaults has saved us here.) There was once a time when I thought the idea of duck typing and implicit casting was convenient and I'm certainly not proud of those days. Coming from a C programming background I should have known better, but I was well and truly caught by the Dark Side™.

    There are few things worse than being asked to maintain some buggy code, that has Option Strict off, and after turning it on you get an error telling you that the amount of errors that can be displayed has been exceeded.

    So how does this all help us to know ourselves better? Do some fancy add-ons to an already confusing product actually make project analysis any easier? The short answer is YES. Basically, the two things you need in order to make effective use of the TFS data warehouse are as follows:

    • Some understanding of DML queries (I can tell you, my T-SQL chops are infantile at best)
    • A solid set of data

    By encouraging your team to create good check-in data with easy to access tools, querying TFS data becomes a much more fruitful experience. If you only have one task to check in against, then querying check-ins really isn't going to give you answers on how long a particular feature took to achieve. Conversely, if you have a rich source control history then ascertaining the amount of time a feature took to implement is a sinch. That's just the beginning; this data store can lead to all sorts of revelations about productivity and quality. It's all about granularity, and it's easy enough to provide. At work we use the following conversion to provide a decent work item tree:

    • Product = Area
    • Feature or functionality = Scenario
    • Aspect of functionality = Task
    • Development cycle (design, create, test etc) = Iteration
    • Bugs are well, bugs of course.

    Areas contain Scenarios, Tasks and bugs are assigned to Iterations. We create related work items from a Scenario when creating a new task or bug, so that they have some link. We don't really bother with Quality of Service or Risk items, but if you feel they apply to your product, by all means use them. We have started to store function specifications into TFS using this convention in order to kill the proverbial two birds. Firstly, it gives us a structured and consistent means of entering a function spec, and also provides a convenient skeleton to create work items from.

    The net result is that if Mr. CEO would like to know how application X is coming along, we can immediately ascertain which scenarios have or haven't been satisfied (I.E % completion). If Mr. Lead Dev wants to know how many tasks to add to an Iteration, he can look up the project velocity report (a standard TFS report) to get a good idea of how quickly his team churns through tasks per day.

    In my next post I will give some examples of querying against the TFS warehouse and how it can make your life a little easier when the boss starts asking the hard questions.


     Friday, June 08, 2007

    Came across this handy technique for testing that methods are raising the correct events. I hope its of use.

    [TestMethod]
    public void RaisesMyEventCorrectly()
    {
      bool lRaised;

      MyObject obj = new MyObject;
      obj.MyEvent += delegate { lRaised = true; };
      MyObjectWithEvents.Method();

      Assert.IsTrue(lRaised, "MyEvent did not fire as expected.");
    }


    Filed under:  |  |  | 
    © Copyright 2008 Jim Burger