Sending an email message in WP7 on unhandled exception
Is there a way to send a email message w开发者_JAVA技巧ith the details when an unhandled exception occurs in a WP7 app?
I've seen the WCF logging/email sending approach, but I don't have a place to publicly host a service.
Take a look at Andy Pennell's "little watson." It works pretty well.
The only other option you have is to use the EmailComposeTask. This leaves you at the mercy of the user to send the message, because it will give you their email address, but its the only way currently to send a mail message without a WCF service.
Example 1:
private void emailAddressChooserTask_Completed(object sender, EmailResult e)
{
if (e.TaskResult == TaskResult.OK)
{
MessageBox.Show("Selected email :" + e.Email);
//in-real world application user expect to select it from his contacts and if not found enter manually.
//EmailComposeTask emailComposeTask = new EmailComposeTask();
//emailComposeTask.To = e.Email;
//emailComposeTask.To = saveEmailAddressTask.Email;
//emailComposeTask.Body = "WP7 Emails Demo";
//emailComposeTask.Cc = "testmail2@test.com";
//emailComposeTask.Subject = "Windows Phone 7";
//emailComposeTask.Show();
}
}
Example 2:
private void composeMail_Click(object sender, RoutedEventArgs e)
{
EmailComposeTask emailComposeTask = new EmailComposeTask();
emailComposeTask.To = "chris@example.com";
emailComposeTask.To = saveEmailAddressTask.Email;
emailComposeTask.Body = "WP7 Emails Demo";
emailComposeTask.Cc = "testmail2@test.com";
emailComposeTask.Subject = "Windows Phone 7";
emailComposeTask.Show();
}
Souce: http://www.windowsphonegeek.com/articles/1-how-to-perform-email-tasks-in-a-wp7-app
I use the following in my app, it is a little convoluted but works. The following code is in App.xaml.cs:
/// <summary>
/// Indicates whether the application needs to quit due to a previous exception
/// </summary>
private static bool _appMustQuit = false;
/// <summary>
/// Exception class that will be unhandled causing application to quit
/// </summary>
private class AppQuitException : Exception {}
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException( object sender,
ApplicationUnhandledExceptionEventArgs e )
{
if( ( e.ExceptionObject is AppQuitException ) == false ) {
Debug.WriteLine( "App:Application_UnhandledException - " + e.ToString() );
if( Debugger.IsAttached ) {
// An unhandled exception has occurred; break into the debugger
Debugger.Break();
}
// Compose error report
StringBuilder report = new StringBuilder( 1024 );
report.AppendFormat( "{0}", LangResources.ErrorReportContent );
report.AppendFormat( "Message: {0}\n", e.ExceptionObject.Message );
if( e.ExceptionObject.InnerException != null ) {
report.AppendFormat( "Inner: {0}\n", e.ExceptionObject.InnerException.Message );
}
report.AppendFormat( "\nStackTrace: {0}\n", e.ExceptionObject.StackTrace );
if( MessageBox.Show( "Unexpected Error", "Error", MessageBoxButton.OKCancel )
== MessageBoxResult.OK ) {
e.Handled = true;
// Email the error report
Tasks.ComposeEmail( "\"Developer\" <your@emailaddress.com>", "MyApp Error Report",
report.ToString() );
_appMustQuit = true;
}
}
}
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated( object sender, ActivatedEventArgs e )
{
var state = PhoneApplicationService.Current.State;
if( state.ContainsKey( "AppMustQuit" ) ) {
throw new AppQuitException();
} else {
// Restore other tombstoned variables
}
}
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated( object sender, DeactivatedEventArgs e )
{
if( _appMustQuit ) {
state["AppMustQuit"] = true;
} else {
// Save other variables for tombstoning
}
}
Tasks
is a static class with a bunch of helper functions from the Microsoft.Phone.Tasks
namespace.
using Microsoft.Phone.Tasks;
namespace MyApp
{
/// <summary>
/// Utility class for performing various phone tasks
/// </summary>
public static class Tasks
{
/// <summary>
/// Composes an email using the specified arguments
/// </summary>
/// <param name="to">The recepient(s) of the email</param>
/// <param name="subject">Email subject</param>
/// <param name="body">Email contents</param>
/// <param name="cc">The recipient(s) on the cc line of the email</param>
public static void ComposeEmail( string to, string subject, string body,
string cc = "" )
{
var task = new EmailComposeTask() {
To = to,
Subject = subject,
Body = body,
Cc = cc,
};
task.Show();
}
}
}
To explain the code a little, using the EmailComposeTask
causes your app to be tombstoned. Since I do not want to continue executing the app after an unhandled exception I save a boolean to the PhoneApplicationService
's State
dictionary so that after the user sends the email, when the app re-awakens I can look for this boolean and throw another exception that is intentionally unhandled. This second exception causes the app to quit.
If somebody is looking for Email messages in background (without loading EmailComposeTask) then MailMessage might be the best option so for, it also allows attachments which EmailComposeTask does not supports at all. it would allow you to send emails without bothering the users in background using your own gmail or anyother account.
you can get it from NuGet Install-Package MailMessage
to give it a try, However I haven't used it myself so may be you need to buy it from authors site its only in $29.99 its really worth paying for it. Free version also works but it shows a popup message in application before sending an email.
精彩评论