views:

151

answers:

4

I have a winforms app and i want to keep track of every time a user clicks certain buttons, etc as well as other actions. What is the best way for me to keep track of this information and then put it together so i can run metrics on most used features, etc.

This is a winforms app and I have users around the world.

A: 

I'd try something like this:

    // execute this method once all forms have been created
    public static void HookButtons()
    {
         foreach( Form f in Application.OpenForms )
         {
           EnumerateControls( f.Controls );
         }
    }

 public static void EnumerateControls( ICollection controls )
 {
  foreach( Control ctrl in controls )
  {
   if( ctrl.Controls.Count > 0 )
   {
    EnumerateControls( ctrl.Controls );
   }

   if( ctrl is ButtonBase )
   {
    ctrl.MouseClick +=new MouseEventHandler( ctrl_MouseClick );
   }
  }

 }

 static void ctrl_MouseClick( object sender, MouseEventArgs e )
 {
  ButtonBase clicked = ((ButtonBase)sender);

  // do something with the click information here
 }
arul
my issue is how to collect and persist this data so i can grab it from all users and then look at trends, etc .
ooo
+1  A: 

Try doing a google scholar search. There are some interesting ideas by Ben Liblit and co-authors, and another series of ideas by Alex Orso and co-authors (disclaimer - I'm one of Alex Orso's co-authors) based on taking a sample of runtime information from each user, and putting it together in an interesting way.

http://theory.stanford.edu/~aiken/publications/papers/pldi03b.pdf

and

http://www.cs.umd.edu/class/fall2006/cmsc838p/Ramss/remoteClassJournal.pdf

are two (not necessarily the best) examples of such papers/ideas.

A: 

Be careful how you handle this. Some companies have gotten user backlash from collecting too much information or not being clear what was collected. The safest way is to ask the user before enabling any "phone home" features. Allowing the user to see the actual data before you send it seems good, too.

I've wondered if there's some way to piggyback on the one-click deployment call that happens whenever a one-click app starts up and checks for updates. I haven't investigated yet, though.

As for collecting the actual numbers, perhaps the user settings are the easiest place. If you're not familiar with them, just check out the project properties and go to the Settings tab.

Don Kirkby
+2  A: 

There are 2 big issues your design has to be sure to address

  1. Privacy (what Don alluded to) - You must be crystal clear what information you are collecting and sending up to your central server, ideally the users should be able to inspect the exact data you are sending back to the central server (if they wish to) - For any public software there should be a very easy way to opt out.

  2. Performance and Scalability - You have to estimate how much data you really need on the server side and look at all sort of tricks that aggregate and compress the data client side (as well as have hard limits on the amount of traffic you will be sending and how often you will be sending it)

As to the client side implementation, I would recommend investigating Sqlite.net or another embedded DB. Using an embedded DB to store this information on the client will give you lots of flexibility with aggregations and will have the advantage of being transactional, fast and simple to implement. Sqlite has a very generous public domain license so from a legal perspective its really easy to use in public apps.

Sam Saffron