LittleWatson: Windows Phone アプリのクラッシュ状況をレポートしてもらう方法
Error Reporting on Windows Phone 7 という記事があります。こちらに、LittleWatsonの実装例が掲載されています。
https://blogs.msdn.com/b/andypennell/archive/2010/11/01/error-reporting-on-windows-phone-7.aspx
この記事からソースを引用する形で、アプリへの組み込みを紹介します。
まずは、LittleWatsonの本体です。単純なクラスです。
// LittleWatson.cs
using System;
using System.Windows;
using System.IO.IsolatedStorage;
using System.IO;
using Microsoft.Phone.Tasks;
namespace YourApp // 作成するアプリに合わせて変更してください。
{
public class LittleWatson
{
const string filename = "LittleWatson.txt";
internal static void ReportException(Exception ex, string extra)
{
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
SafeDeleteFile(store);
using (TextWriter output = new StreamWriter(store.CreateFile(filename)))
{
output.WriteLine(extra);
output.WriteLine(ex.Message);
output.WriteLine(ex.StackTrace);
}
}
}
catch (Exception)
{
}
}
internal static void CheckForPreviousException()
{
try
{
string contents = null;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(filename))
{
using (TextReader reader = new StreamReader(store.OpenFile(filename, FileMode.Open, FileAccess.Read, FileShare.None)))
{
contents = reader.ReadToEnd();
}
SafeDeleteFile(store);
}
}
if (contents != null)
{
if (MessageBox.Show("A problem occurred the last time you ran this application. Would you like to send an email to report it?", "Problem Report", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{
EmailComposeTask email = new EmailComposeTask();
email.To = "someone@example.com"; // レポートを受け取りたいメールアドレスを指定します
email.Subject = "YourAppName auto-generated problem report";
email.Body = contents;
SafeDeleteFile(IsolatedStorageFile.GetUserStoreForApplication()); // line added 1/15/2011
email.Show();
}
}
}
catch (Exception)
{
}
finally
{
SafeDeleteFile(IsolatedStorageFile.GetUserStoreForApplication());
}
}
private static void SafeDeleteFile(IsolatedStorageFile store)
{
try
{
store.DeleteFile(filename);
}
catch (Exception ex)
{
}
}
}
}
続いて、例外を記録する処理をApp.xaml.csに仕込みます。黄色でハイライトした部分が追加のコードです。
// ナビゲーションに失敗した場合に実行されるコード
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
LittleWatson.ReportException(e.Exception, DateTime.Now.ToString()+"> NavigationFailed:"+e.Uri.ToString());
if (System.Diagnostics.Debugger.IsAttached)
{
// ナビゲーションに失敗しました。デバッガーで中断します。
System.Diagnostics.Debugger.Break();
}
}
// ハンドルされない例外の発生時に実行されるコード
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
LittleWatson.ReportException(e.ExceptionObject, DateTime.Now.ToString() + "> UnhandledException");
if (System.Diagnostics.Debugger.IsAttached)
{
// ハンドルされない例外が発生しました。デバッガーで中断します。
System.Diagnostics.Debugger.Break();
}
}
最後に、アプリ起動時に表示されるページの読み込み時に、前回発生した例外をチェックします。
前回にクラッシュしていれば、メッセージを表示し、メールを作成します。
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
LittleWatson.CheckForPreviousException();
}
実行例:
メールの例:
--------
2012/07/19 19:48:36> UnhandledException
DivideByZeroException
at TweetsSearch.MainPage.button1_Click(Object sender,
RoutedEventArgs e)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs
e)
at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control
ctrl, EventArgs e)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr
unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String
eventName)
Sent from Windows Phone IS12T
--------
LittleWatson、皆さんも活用してはいかがでしょうか。