使用 HockeyApp(Windows) 发送已处理的异常报告
Send handled Exception report using HockeyApp(Windows)
我正在尝试使用 hockeyapp 发送错误报告,而不必让整个应用崩溃和燃烧。我不认为 HockeyApp.WPF 库有这个能力,所以我开始胡思乱想实现我自己的 CrashHandler。
这很快就变得令人困惑,而且非常骇人听闻。有人有这方面的代码示例吗?以我目前的速度,我将最终复制 HockeyApp 库的一半,因此我将不胜感激。
我没有 post 编写我的代码,因为我认为它不会有帮助而且太多了。
编辑:现在我将 post 一个似乎不起作用的简化代码版本:
private static void HandleException(Exception e) {
try {
string crashID = Guid.NewGuid().ToString();
String filename = String.Format("{0}{1}.log", CrashFilePrefix, crashID);
CrashLogInformation logInfo = new CrashLogInformation() {
PackageName = Application.Current.GetType().Namespace,
Version = ((HockeyClient)HockeyClient.Current).VersionInfo,
OperatingSystem = Environment.OSVersion.Platform.ToString(),
Windows = Environment.OSVersion.Version.ToString() + Environment.OSVersion.ServicePack,
Manufacturer = "",
Model = ""
};
ICrashData crash = ((HockeyClient)HockeyClient.Current).CreateCrashData(e);
using (FileStream stream = File.Create(Path.Combine(GetPathToHockeyCrashes(), filename))) {
crash.Serialize(stream);
stream.Flush();
}
}
catch (Exception ex) {
((HockeyClient)HockeyClient.Current).HandleInternalUnhandledException(ex);
}
}
private static string GetPathToHockeyCrashes() {
string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (!path.EndsWith("\")) { path += "\"; }
path += "HockeyCrashes\";
if (!Directory.Exists(path)) { Directory.CreateDirectory(path); }
return path;
}
private struct CrashLogInformation {
/// <summary>
/// name of app package
/// </summary>
public string PackageName;
/// <summary>
/// version of app
/// </summary>
public string Version;
/// <summary>
/// os
/// </summary>
public string OperatingSystem;
/// <summary>
/// device manufacturer
/// </summary>
public string Manufacturer;
/// <summary>
/// device model
/// </summary>
public string Model;
/// <summary>
/// product id of app
/// </summary>
public string ProductID;
/// <summary>
/// windows phone version
/// </summary>
public string WindowsPhone;
/// <summary>
/// windows version
/// </summary>
public string Windows;
}
按照 crashes/upload 端点 (http://support.hockeyapp.net/kb/api/api-crashes#-u-post-api-2-apps-app_id-crashes-upload-u-).
的文档中所述格式化日志后,我能够制作 post
虽然我最终点击了 "crashes/",但根据我的理解,这与 crashes/upload 不同(因此这是一个点击未记录端点的解决方案)。
private static readonly string HOCKEYUPLOADURL = @"https://rink.hockeyapp.net/api/2/apps/{0}/crashes/";
private static async Task SendDataAsync(String log, String userID, String contact, String description) {
string rawData = "";
rawData += "raw=" + Uri.EscapeDataString(log);
if (userID != null) {
rawData += "&userID=" + Uri.EscapeDataString(userID);
}
if (contact != null) {
rawData += "&contact=" + Uri.EscapeDataString(contact);
}
if (description != null) {
rawData += "&description=" + Uri.EscapeDataString(description);
}
WebRequest request = WebRequest.Create(new Uri(String.Format(HOCKEYUPLOADURL, HOCKEYAPPID)));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (Stream stream = await request.GetRequestStreamAsync()) {
byte[] byteArray = Encoding.UTF8.GetBytes(rawData);
stream.Write(byteArray, 0, rawData.Length);
stream.Flush();
}
try {
using (WebResponse response = await request.GetResponseAsync()) { }
}
catch (WebException e) {
WriteLocalLog(e, "HockeyApp SendDataAsync failed");
}
}
我正在尝试使用 hockeyapp 发送错误报告,而不必让整个应用崩溃和燃烧。我不认为 HockeyApp.WPF 库有这个能力,所以我开始胡思乱想实现我自己的 CrashHandler。
这很快就变得令人困惑,而且非常骇人听闻。有人有这方面的代码示例吗?以我目前的速度,我将最终复制 HockeyApp 库的一半,因此我将不胜感激。
我没有 post 编写我的代码,因为我认为它不会有帮助而且太多了。
编辑:现在我将 post 一个似乎不起作用的简化代码版本:
private static void HandleException(Exception e) {
try {
string crashID = Guid.NewGuid().ToString();
String filename = String.Format("{0}{1}.log", CrashFilePrefix, crashID);
CrashLogInformation logInfo = new CrashLogInformation() {
PackageName = Application.Current.GetType().Namespace,
Version = ((HockeyClient)HockeyClient.Current).VersionInfo,
OperatingSystem = Environment.OSVersion.Platform.ToString(),
Windows = Environment.OSVersion.Version.ToString() + Environment.OSVersion.ServicePack,
Manufacturer = "",
Model = ""
};
ICrashData crash = ((HockeyClient)HockeyClient.Current).CreateCrashData(e);
using (FileStream stream = File.Create(Path.Combine(GetPathToHockeyCrashes(), filename))) {
crash.Serialize(stream);
stream.Flush();
}
}
catch (Exception ex) {
((HockeyClient)HockeyClient.Current).HandleInternalUnhandledException(ex);
}
}
private static string GetPathToHockeyCrashes() {
string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (!path.EndsWith("\")) { path += "\"; }
path += "HockeyCrashes\";
if (!Directory.Exists(path)) { Directory.CreateDirectory(path); }
return path;
}
private struct CrashLogInformation {
/// <summary>
/// name of app package
/// </summary>
public string PackageName;
/// <summary>
/// version of app
/// </summary>
public string Version;
/// <summary>
/// os
/// </summary>
public string OperatingSystem;
/// <summary>
/// device manufacturer
/// </summary>
public string Manufacturer;
/// <summary>
/// device model
/// </summary>
public string Model;
/// <summary>
/// product id of app
/// </summary>
public string ProductID;
/// <summary>
/// windows phone version
/// </summary>
public string WindowsPhone;
/// <summary>
/// windows version
/// </summary>
public string Windows;
}
按照 crashes/upload 端点 (http://support.hockeyapp.net/kb/api/api-crashes#-u-post-api-2-apps-app_id-crashes-upload-u-).
的文档中所述格式化日志后,我能够制作 post虽然我最终点击了 "crashes/",但根据我的理解,这与 crashes/upload 不同(因此这是一个点击未记录端点的解决方案)。
private static readonly string HOCKEYUPLOADURL = @"https://rink.hockeyapp.net/api/2/apps/{0}/crashes/";
private static async Task SendDataAsync(String log, String userID, String contact, String description) {
string rawData = "";
rawData += "raw=" + Uri.EscapeDataString(log);
if (userID != null) {
rawData += "&userID=" + Uri.EscapeDataString(userID);
}
if (contact != null) {
rawData += "&contact=" + Uri.EscapeDataString(contact);
}
if (description != null) {
rawData += "&description=" + Uri.EscapeDataString(description);
}
WebRequest request = WebRequest.Create(new Uri(String.Format(HOCKEYUPLOADURL, HOCKEYAPPID)));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (Stream stream = await request.GetRequestStreamAsync()) {
byte[] byteArray = Encoding.UTF8.GetBytes(rawData);
stream.Write(byteArray, 0, rawData.Length);
stream.Flush();
}
try {
using (WebResponse response = await request.GetResponseAsync()) { }
}
catch (WebException e) {
WriteLocalLog(e, "HockeyApp SendDataAsync failed");
}
}