自動デバッグツール

だから、状況を想像してください。 プログラムを作成し、テスト用に送信すると、テスターがエラーを見つけました。 そのアクション-レターを作成し、このエラーを説明し、再生の手順を説明し、スクリーンショットを撮り、レターにスクリーンショットを添付して送信します。



彼の仕事をもっと楽にしましょう。



これを行うには、キーストロークをインターセプトしてシャーマニズムを生成するHotKeyクラス、私に新しい手紙をすぐに表示するMAPIラッパークラス、およびすべての情報を収集して作業を行うDebugToolクラス自体が必要です。





HotKeyクラスはuser32.dllライブラリを使用して、特定のキーの組み合わせ(RegisterHotKeyメソッド)のイベントを登録します。そのようなキーの組み合わせが既に登録されている場合、ApplicationExceptionがスローされます(「Hotkey already in use」)。



プログラムで、Ctrl-Shift-BイベントOnBugHandleにイベントを登録します。



public static HotKey hotKey = new HotKey(Keys.B, HotKey.KeyModifiers.Control | HotKey.KeyModifiers.Shift, new EventHandler(OnBugHandle));







OnBugHandleは、静的メソッドDebugTool.ProcessBug()を呼び出します。



public static void OnBugHandle(object obj, EventArgs args)

{

DebugTool.ProcessBug();

}







次に、MAPIラッパークラスに移りましょう。 このクラスにより、開発者に送信するためのレターを作成できます。



それでは、メインのDebugToolクラスに移りましょう。 このクラスは次のことを行う必要があります。







さらに、DebugToolでOnUnhandledExceptionイベントを処理させ、個別の呼び出しスタックファイルと例外自体に書き込みます。



スクリーンショットを撮る:

private static void MakeScreenshot()

{

Bitmap Bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,

Screen.PrimaryScreen.Bounds.Height,

PixelFormat.Format32bppArgb);

Graphics Graphic = Graphics.FromImage(Bitmap);

Graphic.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,

Screen.PrimaryScreen.Bounds.Y,

0, 0,

Screen.PrimaryScreen.Bounds.Size,

CopyPixelOperation.SourceCopy);

Bitmap.Save(tempPath + "screenshot.bmp");

}








TempPathは一時フォルダーであり、Path.GetTempPath()を介して要求できます。 そこで、アーカイブする必要があるすべてのファイルを収集します。



呼び出しスタックファイルの保存:



private static void SaveStack()

{

using (TextWriter textWriter = new StreamWriter(

new FileStream(tempPath + "stack.txt", FileMode.Create, FileAccess.Write),

Encoding.Unicode))

{



StackTrace st = new StackTrace(true);

for (int i = 0; i < st.FrameCount; i++)

{

StackFrame sf = st.GetFrame(i);

textWriter.WriteLine(string.Empty);

textWriter.WriteLine("Method: {0}", sf.GetMethod());

textWriter.WriteLine("Line Number: {0}", sf.GetFileLineNumber());

}

}

}







例外データの保存(すべての内部例外の再帰的な記録):



private static void ExceptionInfo(Exception ex)

{

Exception currentException = ex;

using (TextWriter textWriter = new StreamWriter(

new FileStream(tempPath + "exception.txt", FileMode.Create, FileAccess.Write),

Encoding.Unicode))

{



while (currentException != null)

{

textWriter.WriteLine(string.Empty);

textWriter.WriteLine("Message : " + currentException.Message);

textWriter.WriteLine("Stack Trace : " + currentException.StackTrace);

textWriter.WriteLine("Source : " + currentException.Source);

currentException = currentException.InnerException;

}

}

}







エラー処理自体。 ここでは、まずスクリーンショットを撮り、次にすべての添付ファイルを一時フォルダーにコピーします。 ZipPackageを使用してzipアーカイブを作成し、このアーカイブを送信します。



public static void ProcessBug()

{

List files = new List();

tempPath = Path.GetTempPath();

MakeScreenshot();



foreach (string BindFile in BindedFiles)

{

if (File.Exists(BindFile))

{

File.Copy(BindFile, tempPath + Path.GetFileName(BindFile), false);

files.Add(Path.GetFileName(BindFile));

}

}



files.Add(Path.GetFileName("screenshot.bmp"));

using (Package package = ZipPackage.Open(tempPath + "package.zip", FileMode.Create))

{

foreach (string fi in files)

{

Uri partUri = PackUriHelper.CreatePartUri(new Uri(fi, UriKind.Relative));

PackagePart packagePart = package.CreatePart(partUri, MediaTypeNames.Text.Plain);



using (FileStream fileStream = new FileStream(tempPath + fi, FileMode.Open, FileAccess.Read))

{

CopyStream(fileStream, packagePart.GetStream());

}

}

package.Flush();

}



SendPackage(BugMessageSubject, tempPath + "package.zip");



foreach (string fi in files)

{

File.Delete(tempPath + fi);

}

File.Delete(tempPath + "package.zip");

}





SendPackage , zip- :



private static void SendPackage(string MessageSubject, string packageFile)

{

try

{

MAPI mapi = new MAPI();

mapi.AddRecipientTo(MessageTo);

mapi.AddAttachment(packageFile);

int sendResult = mapi.SendMailPopup(MessageSubject, MessageBody);

if (sendResult > 1)

{

string DesktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

File.Copy(packageFile, DesktopFolder + "\\bug_" + Path.GetFileNameWithoutExtension(packageFile)

+ "_" + DateTime.Now.ToString("yyyyMMddHHmm") + Path.GetExtension(packageFile), true);

MessageBox.Show("I'd copyed package.zip into desktop. Send it.");

}

}

catch (Exception ex)

{

MessageBox.Show("Can't process. Exception :" + ex.Message);

}

}









OnUnhandledException.



:

static void Main()

{

...

// UnhandledException

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ProcessUnhandledException);

//

DebugTool.BindedFiles.Add(“logs.log”);

// MAPI

DebugTool.MessageTo = "...@gmail.com";

DebugTool.UnhandledMessageSubject = "Unhandled exception in your application";

DebugTool.BugMessageSubject = "Bug in application";

DebugTool.MessageBody = "<Please, leave here your comment>";

}



private static void ProcessUnhandledException(object sender, UnhandledExceptionEventArgs e)

{

DebugTool.ProcessUnhandledException(e);

}









! , Ctrl-Shift-B .










All Articles