[WPF] 使用 Visual Studio App Center 持續監視應用使用情況和問題

1. 什麼是AppCenter

Visual Studio App Center 是幾個常見移動開發和雲集成服務(如持續集成、持續交付和自動 UI 測試等服務)的集合。 這些 App Center 服務可以針對 iOS、Android、WPF/Winforms、通用 Windows 平台 (UWP) 和 tvOS 應用運行。

App Center 服務使開發人員可以輕鬆地生成、測試和分發應用程序。 應用由測試人員或客戶使用之後,App Center 會提供服務來監視其應用的使用情況和問題。

作為一個桌面軟件開發人員我很關心軟件的使用情況,但又偏偏很難獲取這些內容,App Center 的診斷和分析功能正好滿足我的需求,而且這兩個功能可以免費使用且十分簡單易用。這篇文章將重點介紹如何在 WPF 項目中使用這兩個功能。

2. 先決條件

  • 你的項目面向的是 .NET Framework 4.6.1 (或更高版本) 或 .NET Core 3.0 (或更高) 版本。
  • 僅當 WPF/WinForms 應用程序在 Windows 上運行時,才支持 .NET Core。
  • 如果你使用的是可移植庫中的 SDK,則它必須面向 .NET standard 1.0 或更高版本, (不支持 PCL) 。

3. 快速入門

首先需要在 App Center 上創建一個應用:

  1. 登錄到 Visual Stuido App Center
  2. 在頁面的右上角單擊 Add New,然後在下拉列表中選擇 Add new app
  3. 在如下圖所示的表單中輸入應用名稱,然後選擇 WindowsWpf
  4. 點擊 Add new app 創建應用。

應用被創建後進入 Overview 頁面,在這裡可以找到 App Center 的入門指南,如下圖所示:

上面打了馬賽克的這段字符是 app secret,每個應用有唯一的 app secret。
在 Nuget 安裝 Microsoft.AppCenter.AnalyticsMicrosoft.AppCenter.Crashes 兩個包。複製上面這段代碼到 App.xaml.cs 的 OnStartup 函數里:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
      base.OnStartup(e);
      AppCenter.Start("******3c-aa79-44d5-94ae-b00e229876b8", typeof(Analytics), typeof(Crashes));
    }
  }
}

完成上述步驟後重啟應用,應用的運行情況將開始自動發送到 App Center,你可以在 Diagnostics (診斷)和 Analytics (分析)頁面看到這些數據。

4. 診斷

診斷頁面中的數據分成兩個部分:Crash(崩潰)和 Error(錯誤)。其中 Crash 由 App Center SDK 自動發送。在使用 App Center SDK,並且應用遇到導致應用崩潰的錯誤時,詳細信息會在應用關閉之前寫入本地存儲。 由於應用遇到了意外錯誤,因此應用所處的狀態不太可靠,不足以將數據發送到 App Center。 但是,當用戶再次啟動應用時,它會將診斷數據發送到 App Center。

而 Error 則由用戶調用 Crashes.TrackError 函數主動發送。

每一個數據都可以看到詳細的錯誤信息,Stack traces,報告時間,同一類數據的 Most affected devices 和 Most affected OS,以及每一個錯誤報告的更具體的信息,如果有使用自定義事件,還可以在 EVENTS 標籤頁中看到 Crash 發生前發生過的事件,以便確定 Crash 發生的原因。

5. 分析

一旦啟用了 App Center SDK,App Center 將自動收集用戶的關鍵指標,包括用戶計數、趨勢、設備、位置、活動時間、國家、語言、版本等。可以在 analytics/overview 查看這些信息。

還可以使用 App Center SDK 發送 Analytics.TrackEvent 函數發送自定義事件。事件可幫助你識別應用程序崩潰的根本原因。 作為 App Center 崩潰服務的一部分,你可以查看在特定會話崩潰之前發生的所有事件。

6. 主動發送數據

一般情況下 App Center Sdk 會自動收集 這些數據,除此之外還可以使用 Analytics.TrackEvent 跟蹤自定義事件。

Analytics.TrackEvent("Video clicked");

也可以在這個函數中的 properties 附加一個 Dictionary:

Analytics.TrackEvent("Video clicked", new Dictionary<string, string> {
    { "Category", "Music" },
    { "FileName", "favorite.avi"}
});

TrackEvent 有一些限制,它最多支持200個不同的事件名稱。每個名稱最多支持256個字符,properties 中每個 key 和 value 的限制都為125個字符,超過的部分將被截斷。

對於已處理的 Exception,可以使用 Crashes.TrackError 跟蹤錯誤:

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

它的用法和 Analytics.TrackEvent 類似。雖然官方文檔沒寫,但字符串的長度限制應該和 Analytics.TrackEvent 一樣。另外它還支持發送文件和文本作為附件:

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);
}

附件的大小限制為 7 MB,嘗試發送更多的附件將觸發錯誤。

7. 處理 Crash

前面提到,崩潰時記錄的數據將再重啟應用時發送到 App Center。這時候我們可以對這些崩潰的信息做些操作。

Crashes.HasCrashedInLastSessionAsync 用於檢查應用是否再上一次啟動時崩潰,Crashes.GetLastSessionCrashReportAsync 用於獲取上次崩潰的詳細信息。

bool didAppCrash = await Crashes.HasCrashedInLastSessionAsync();
ErrorReport crashReport = await Crashes.GetLastSessionCrashReportAsync();

如果你覺得有些崩潰不需要發送到 App Center,可以在 ShouldProcessErrorReport 回調中返回 false。

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

如果需要發送更詳細的崩潰報告,可以使用 GetErrorAttachments 回調添加附件,這個附件將聯通 Crash 數據一起發送。

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")
    };
};

如果想在發送報告前彈個框問問用戶要不要發送,可以在 ShouldAwaitUserConfirmation 回調中返回 true 並構建 UI,然後用 Crashes.NotifyUserConfirmation 通知 SDK 發送消息:

Crashes.ShouldAwaitUserConfirmation = ConfirmationHandler;
private static bool ConfirmationHandler()
{
    Current.Dispatcher.InvokeAsync(() =>
    {
        var dialog = new UserConfirmationDialog();
        if (dialog.ShowDialog() ?? false)
        {
            Crashes.NotifyUserConfirmation(dialog.ClickResult);
        }
    });
    return true;
}

8. 最後

App Center 通過診斷和分析兩個功能監視應用的實際情況,完善應用開發生命周期的最後一步,幫助開發人員構建更好的應用程序。更多的信息可以參考下面的鏈接:

Visual Studio 應用中心
Visual Studio 應用中心定價
Visual Studio 應用中心常見問題
Visual Studio App Center文檔
App Center 簡介 – Learn Microsoft Docs
microsoft/appcenter-sdk-dotnet: Development repository for the App Center SDK for .NET platforms, including Xamarin