彼の仕事をもっと楽にしましょう。
これを行うには、キーストロークをインターセプトしてシャーマニズムを生成する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 .