重要
Visual Studio App Center 于 2025 年 3 月 31 日停用,但分析和诊断功能除外,这些功能将继续受支持,直到 2026 年 6 月 30 日。 了解详细信息。
每次应用发生崩溃时,App Center Crashes 功能都会自动生成一份崩溃日志。 日志首先写入设备的存储,当用户再次启动应用时,崩溃报告将发送到 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,这非常有用。 一些开发人员选择显示额外的用户界面,表达对用户的歉意,并希望在发生崩溃后能与用户取得联系。
注释
此方法应仅在 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
;Crashes 模块会自动为您处理日志发送。
以下回调演示如何告知 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 Crashes,请使用相同的 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);
}