My standard disclaimer: I am a developer on this product.
Using a product (Runtime Intelligence) written by the company I work for (PreEmptive Soltutions) you can inject not only error reporting but also the ability to track when users are using your applications and what features they are using with minimal coding.
Using Dotfuscator to perform code injection (or IL weaving) we insert new code into your application binaries that sends usage data back to a server hosted at our facility (or optionally to any other arbitrary URL). If you send the data to us we provide you with a number of powerful analysis tools and reports on usage.
A basic version of this functionality is to be included in Visual Studio 2010 as well as access to a free data reporting portal (but with no SLA's, data retention guarantees or data privacy).
The ability to send arbitrary data back along with the usage information is limited to the commercial product, but you can contact PreEmptive Soltutions for a fully functional, free time limited evaluation version.
You can accomplish error reporting with the sample code below:
public partial class app : Application {
// field to temporarily store exception data
private Exception exp;
void AppStartup(object sender, StartupEventArgs args) {
// add a handler to catch any unhandled exceptions
this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(ErrorHandler);
Window1 mainWindow = new Window1();
mainWindow.ShowDialog();
}
// this will prompt the user if they want to report the exception
void ErrorHandler(object sender, DispatcherUnhandledExceptionEventArgs e) {
this.exp = e.Exception;
if (MessageBox.Show("A " + exp.Message + " exception happened, should I report it?", "Error Occurrend", MessageBoxButton.YesNo) == MessageBoxResult.Yes) {
ErrorHappened();
e.Handled = true;
}
}
// this method is called by the above ErrorHandler method and when run through Dotfuscator additional code will be injected into this method that will send a usage data message back to the server and the data in the dictionary (which will be exception data) returned by the ErrorData method will be included into the message and be stored and reported on the server
[Feature("Exception", EventType = FeatureEventTypes.Tick, ExtendedKeySourceElement = SourceElements.Method, ExtendedKeySourceName = "ErrorData")]
private void ErrorHappened() {
// This is here as a placeholder for the exception feature attribute which will exit the application when executed
AppShutdown(true);
}
// this method takes the exception data from the exp field and returns it as a dictionary of name/value pairs
public Dictionary<string, string> ErrorData() {
var retval = new Dictionary<string,string>();
if (null != exp) {
retval.Add("Error Message",exp.Message);
retval.Add("Stack Trace",exp.StackTrace);
}
return retval;
}
}