Windows (App Center 崩溃)

每次应用崩溃时,App Center 崩溃都将自动生成崩溃日志。 日志首先写入设备的存储,当用户再次启动应用时,系统会将故障报告发送到 App Center。

App Center SDK 只收集未处理的 .NET 异常导致的故障。 当使用 C 或 c + + 时,它不会收集本机崩溃。 但是,如果应用程序的 c + + 发生故障,则可以通过 上传崩溃 API将其上传到 App Center。

如果尚未在应用程序中设置 SDK,请遵循 WPF/WinForms 入门

WinForms 应用程序上的未经处理的异常

备注

本节和后面的子节仅适用于 WinForms。 如果要在 WPF 上集成 SDK,则可以跳过此部分。

默认情况下,WinForms 应用程序中的未经处理的异常不会触发故障 (应用程序不会退出) 如果未附加调试器,则不会退出。

相反,Windows 向用户显示一个对话框,用于继续或退出应用程序执行。 因此,即使用户单击 " 退出 " 按钮) ,App Center SDK 仍无法自动捕获这些例外情况 (。

仅当在 App Center 会导致应用程序自动退出时,才会收集故障。 每个会话 App Center 仅支持一个故障。

可以通过两种方式在 WinForms 中报告未经处理的异常。 应用程序可以配置为在未经处理的异常上崩溃,或继续运行,但将未经处理的异常报告为运行时错误。

将应用程序配置为在崩溃时退出

这是将未经处理的异常报告为 App Center 崩溃 的唯一方法,使应用程序在发生未经处理的异常时退出。

为此,请在初始化 SDK 之前调用 Windows 方法:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
AppCenter.Start(...);

如果你的应用程序中不接受此选项,你可以将未处理的异常报告为运行时错误 (如下) 所述。

将未经处理的异常报告为运行时错误

如果在发生未经处理的异常后,应用程序必须保持运行状态,则无法将异常报告为 App Center 中的 故障 ,但你可以将其报告为 错误

为此,可以使用以下代码示例:

Application.ThreadException += (sender, args) =>
{
    Crashes.TrackError(args.Exception);
};
AppCenter.Start(...);

备注

附加调试器时,未经处理的异常会导致应用程序退出 (崩溃) 除非 将处理程序附加到 Application.ThreadException

生成测试崩溃

App Center 崩溃将为你提供一个 API,用于生成测试崩溃以便轻松测试 SDK。 此 API 检查调试和发布配置。 因此,你只能在调试时使用它,因为它不适用于发布应用程序。

Crashes.GenerateTestCrash();

获取有关以前的故障的详细信息

App Center 崩溃具有两个 Api,可提供有关应用崩溃情况的详细信息。

应用在上一个会话中是否崩溃?

启动 SDK 之后,可以随时检查应用是否在上一次启动时崩溃:

bool didAppCrash = await Crashes.HasCrashedInLastSessionAsync();

如果你想要在发生崩溃后调整应用的行为或 UI,这会很方便。 某些开发人员选择向其用户显示额外的 UI,或者希望在发生崩溃后进行触摸。

备注

此方法只能在启动后使用 Crashes ,它将始终 false 在开始之前返回。

有关上次崩溃的详细信息

如果应用之前崩溃,可以获取有关上次崩溃的详细信息。

ErrorReport crashReport = await Crashes.GetLastSessionCrashReportAsync();

备注

此方法只能在启动后 Crashes 使用,它始终在启动 null 之前返回。

此 API 有许多用例,最常见的用例是调用此 API 并实施其自定义 故障委托或侦听器 的用户

自定义崩溃App Center使用情况

App Center崩溃为开发人员提供回调,以在将故障日志发送到 App Center 之前和时间执行其他操作。

备注

在调用 之前 设置 回调 AppCenter.Start() ,App Center开始处理后立即崩溃。

应该处理故障吗?

如果要确定是否需要处理特定崩溃,则设置此回调。 例如,有一个系统级崩溃,你想要忽略它,并且你不想发送到App Center。

Crashes.ShouldProcessErrorReport = (ErrorReport report) =>
{
    // Check the report in here and return true or false depending on the ErrorReport.
    return true;
};

如果用户隐私很重要,你可能想要在向用户发送故障报告之前获得用户App Center。 SDK 公开一个回调,该回调App Center在发送任何故障报告之前等待用户确认。

如果选择这样做,则你负责获取用户的确认,例如,通过包含以下选项之一的对话提示:"始终 发送"、"发送"和"不发送"。 根据输入,你将告知App Center崩溃要执行哪些操作,然后会相应地处理崩溃。

备注

SDK 不显示此对话框,应用必须提供自己的 UI 以请求用户同意。

备注

如果应用未实现用户确认对话框,则不应显式调用 ; NotifyUserConfirmation 崩溃模块将处理隐式发送日志。

以下回调演示如何告知 SDK 在发送崩溃之前等待用户确认:

Crashes.ShouldAwaitUserConfirmation = () =>
{
    // Build your own UI to ask for user consent here. SDK doesn't provide one by default.

    // Return true if you built a UI for user consent and are waiting for user input on that custom UI, otherwise false.
    return true;
};

如果你在 true 上面的回调中返回,你的应用程序必须使用你自己的代码) 用户权限获取 (,并使用以下 API 通过该结果向 SDK 发送消息。

// Depending on the user's choice, call Crashes.NotifyUserConfirmation() with the right value.
Crashes.NotifyUserConfirmation(UserConfirmation.DontSend);
Crashes.NotifyUserConfirmation(UserConfirmation.Send);
Crashes.NotifyUserConfirmation(UserConfirmation.AlwaysSend);

获取有关崩溃日志的发送状态的信息

有时,您需要了解应用程序崩溃的状态。 常见的用例是,你可能希望显示 UI,告诉用户应用正在提交故障报告,或者,如果你的应用程序在启动后很快崩溃,你需要调整应用程序的行为,以确保能够提交故障日志。 App Center 崩溃提供三个不同的回调,你可以在应用中使用这些回调来通知你发生了什么情况:

在 SDK 发送崩溃日志之前,将调用以下回调

Crashes.SendingErrorReport += (sender, e) =>
{
    // Your code, e.g. to present a custom UI.
};

如果在终结点上出现网络问题或中断,重新启动应用程序, SendingErrorReport 则会在进程重新启动后再次触发。

SDK 成功发送故障日志后将调用以下回调

Crashes.SentErrorReport += (sender, e) =>
{
    // Your code, e.g. to hide the custom UI.
};

如果 SDK 未能发送崩溃日志,将调用以下回调

Crashes.FailedToSendErrorReport += (sender, e) =>
{
    // Your code goes here.
};

接收 FailedToSendErrorReport 意味着出现错误,如发生 4xx 代码。 例如, 401 表示 appSecret 错误。

如果这是网络问题,则不会触发此回调。 在这种情况下,SDK 会继续重试 (,还会在网络连接关闭) 时暂停重试。

向崩溃报表添加附件

您可以向崩溃报表添加二进制和文本附件。 SDK 会将它们连同崩溃一起发送,以便您可以在 App Center 门户中查看它们。 在从以前的应用程序启动中发送存储的崩溃之前,将直接调用以下回调。 发生故障时,不会调用此方法。 请确保附件文件 命名 minidump.dmp ,因为该名称已保留用于小型转储文件。 下面的示例演示如何将文本和图像附加到崩溃:

Crashes.GetErrorAttachments = (ErrorReport report) =>
{
    // Your code goes here.
    return new ErrorAttachmentLog[]
    {
        ErrorAttachmentLog.AttachmentWithText("Hello world!", "hello.txt"),
        ErrorAttachmentLog.AttachmentWithBinary(Encoding.UTF8.GetBytes("Fake image"), "fake_image.jpeg", "image/jpeg")
    };
};

备注

大小限制当前为 7 MB。 尝试发送更大的附件将触发错误。

启用或禁用App Center崩溃

可以在运行时启用和App Center崩溃。 如果禁用它,SDK 将不会对应用执行任何崩溃报告。

Crashes.SetEnabledAsync(false);

若要再次App Center崩溃,请使用同一 API,但作为 true 参数传递。

Crashes.SetEnabledAsync(true);

无需等待此调用,使其他 API 调用 (一) IsEnabledAsync 一致。

状态在应用程序启动时一直保留于设备的存储中。

检查App Center崩溃是否已启用

还可以检查是否App Center崩溃:

bool isEnabled = await Crashes.IsEnabledAsync();

已处理的错误

App Center还允许使用已处理的异常跟踪错误。 为此,请使用 TrackError 方法:

try {
    // your code goes here.
} catch (Exception exception) {
    Crashes.TrackError(exception);
}

应用可以选择性地将属性附加到已处理的错误报告,以提供进一步上下文。 将属性作为键/值对字典传递 (字符串) 如以下示例所示。

try {
    // your code goes here.
} catch (Exception exception) {
    var properties = new Dictionary<string, string>
    {
        { "Category", "Music" },
        { "Wifi", "On"}
    };
    Crashes.TrackError(exception, properties); 
}

还可以选择将二进制和文本附件添加到已处理的错误报告。 将附件作为 对象的数组 ErrorAttachmentLog 传递,如以下示例所示。

try {
    // your code goes here.
} catch (Exception exception) {
    var attachments = new ErrorAttachmentLog[]
    {
        ErrorAttachmentLog.AttachmentWithText("Hello world!", "hello.txt"),
        ErrorAttachmentLog.AttachmentWithBinary(Encoding.UTF8.GetBytes("Fake image"), "fake_image.jpeg", "image/jpeg")
    };
    Crashes.TrackError(exception, attachments: attachments);
}