Merge pull request #1549 from microsoft/feature/support-winui-sdk

Add support WinUI
This commit is contained in:
Dima 2021-08-04 12:52:07 +03:00 коммит произвёл GitHub
Родитель 7f9fb61afb d3a2953079
Коммит aeffd7b8bc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
61 изменённых файлов: 2455 добавлений и 19 удалений

Просмотреть файл

@ -104,6 +104,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contoso.WinForms.Demo.DotNe
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contoso.UtilClassLibrary", "Apps\Contoso.UtilClassLibrary\Contoso.UtilClassLibrary.csproj", "{A42BE92C-616D-4333-9F6A-D05BA547BFC6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Contoso.WinUI", "Contoso.WinUI", "{9D91A723-8B16-40D1-8816-48DB05AFA708}"
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Contoso.WinUI.Desktop.Puppet (Package)", "Apps\Contoso.WinUI.Desktop.Puppet\Contoso.WinUI.Desktop.Puppet (Package)\Contoso.WinUI.Desktop.Puppet (Package).wapproj", "{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contoso.WinUI.Desktop.Puppet", "Apps\Contoso.WinUI.Desktop.Puppet\Contoso.WinUI.Desktop.Puppet\Contoso.WinUI.Desktop.Puppet.csproj", "{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}"
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Contoso.WinUI.Desktop.Demo (Package)", "Apps\Contoso.WinUI.Desktop.Demo\Contoso.WinUI.Desktop.Demo (Package)\Contoso.WinUI.Desktop.Demo (Package).wapproj", "{40123B52-AE63-4A0A-8661-3644BEDE411D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contoso.WinUI.Desktop.Demo", "Apps\Contoso.WinUI.Desktop.Demo\Contoso.WinUI.Desktop.Demo\Contoso.WinUI.Desktop.Demo.csproj", "{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
Tests\Microsoft.AppCenter.Test.WindowsDesktop.Shared\Microsoft.AppCenter.Test.WindowsDesktop.Shared.projitems*{09f38506-8def-431d-a749-df7e73a719f0}*SharedItemsImports = 13
@ -795,6 +805,82 @@ Global
{A42BE92C-616D-4333-9F6A-D05BA547BFC6}.Release|x64.Build.0 = Release|Any CPU
{A42BE92C-616D-4333-9F6A-D05BA547BFC6}.Release|x86.ActiveCfg = Release|Any CPU
{A42BE92C-616D-4333-9F6A-D05BA547BFC6}.Release|x86.Build.0 = Release|Any CPU
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|Any CPU.ActiveCfg = Debug|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|ARM.ActiveCfg = Debug|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|ARM64.ActiveCfg = Debug|arm64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|ARM64.Build.0 = Debug|arm64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|ARM64.Deploy.0 = Debug|arm64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|x64.ActiveCfg = Debug|x64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|x64.Build.0 = Debug|x64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|x64.Deploy.0 = Debug|x64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|x86.ActiveCfg = Debug|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|x86.Build.0 = Debug|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Debug|x86.Deploy.0 = Debug|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|Any CPU.ActiveCfg = Release|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|ARM.ActiveCfg = Release|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|ARM64.ActiveCfg = Release|arm64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|ARM64.Build.0 = Release|arm64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|ARM64.Deploy.0 = Release|arm64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|x64.ActiveCfg = Release|x64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|x64.Build.0 = Release|x64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|x64.Deploy.0 = Release|x64
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|x86.ActiveCfg = Release|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|x86.Build.0 = Release|x86
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7}.Release|x86.Deploy.0 = Release|x86
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Debug|Any CPU.ActiveCfg = Debug|x86
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Debug|ARM.ActiveCfg = Debug|x86
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Debug|ARM64.ActiveCfg = Debug|arm64
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Debug|ARM64.Build.0 = Debug|arm64
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Debug|x64.ActiveCfg = Debug|x64
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Debug|x64.Build.0 = Debug|x64
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Debug|x86.ActiveCfg = Debug|x86
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Debug|x86.Build.0 = Debug|x86
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Release|Any CPU.ActiveCfg = Release|x86
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Release|ARM.ActiveCfg = Release|x86
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Release|ARM64.ActiveCfg = Release|arm64
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Release|ARM64.Build.0 = Release|arm64
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Release|x64.ActiveCfg = Release|x64
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Release|x64.Build.0 = Release|x64
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Release|x86.ActiveCfg = Release|x86
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD}.Release|x86.Build.0 = Release|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|Any CPU.ActiveCfg = Debug|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|ARM.ActiveCfg = Debug|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|ARM64.ActiveCfg = Debug|arm64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|ARM64.Build.0 = Debug|arm64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|ARM64.Deploy.0 = Debug|arm64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|x64.ActiveCfg = Debug|x64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|x64.Build.0 = Debug|x64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|x64.Deploy.0 = Debug|x64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|x86.ActiveCfg = Debug|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|x86.Build.0 = Debug|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Debug|x86.Deploy.0 = Debug|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|Any CPU.ActiveCfg = Release|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|ARM.ActiveCfg = Release|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|ARM64.ActiveCfg = Release|arm64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|ARM64.Build.0 = Release|arm64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|ARM64.Deploy.0 = Release|arm64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|x64.ActiveCfg = Release|x64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|x64.Build.0 = Release|x64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|x64.Deploy.0 = Release|x64
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|x86.ActiveCfg = Release|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|x86.Build.0 = Release|x86
{40123B52-AE63-4A0A-8661-3644BEDE411D}.Release|x86.Deploy.0 = Release|x86
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Debug|Any CPU.ActiveCfg = Debug|x86
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Debug|ARM.ActiveCfg = Debug|x86
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Debug|ARM64.ActiveCfg = Debug|arm64
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Debug|ARM64.Build.0 = Debug|arm64
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Debug|x64.ActiveCfg = Debug|x64
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Debug|x64.Build.0 = Debug|x64
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Debug|x86.ActiveCfg = Debug|x86
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Debug|x86.Build.0 = Debug|x86
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Release|Any CPU.ActiveCfg = Release|x86
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Release|ARM.ActiveCfg = Release|x86
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Release|ARM64.ActiveCfg = Release|arm64
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Release|ARM64.Build.0 = Release|arm64
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Release|x64.ActiveCfg = Release|x64
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Release|x64.Build.0 = Release|x64
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Release|x86.ActiveCfg = Release|x86
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -843,6 +929,11 @@ Global
{5BFC9B9D-FD5B-4BFB-8079-DD7A686B1FEE} = {AA6821F3-930A-49E4-BA3F-D68255F39F1E}
{C795494B-561C-4668-93CC-6BB4CA78A70F} = {AA6821F3-930A-49E4-BA3F-D68255F39F1E}
{A42BE92C-616D-4333-9F6A-D05BA547BFC6} = {AA6821F3-930A-49E4-BA3F-D68255F39F1E}
{9D91A723-8B16-40D1-8816-48DB05AFA708} = {AA6821F3-930A-49E4-BA3F-D68255F39F1E}
{345565C8-4971-4D1A-88CC-F7CBDAE2C7C7} = {9D91A723-8B16-40D1-8816-48DB05AFA708}
{CFBCABA9-EB43-41E2-8605-67A583BA3ACD} = {9D91A723-8B16-40D1-8816-48DB05AFA708}
{40123B52-AE63-4A0A-8661-3644BEDE411D} = {9D91A723-8B16-40D1-8816-48DB05AFA708}
{9AC0B3BE-BB5E-4E42-836D-DD44E7CD1E96} = {9D91A723-8B16-40D1-8816-48DB05AFA708}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {328868E2-F749-412D-B82F-84A683A1719C}

Просмотреть файл

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'">
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|arm64">
<Configuration>Debug</Configuration>
<Platform>arm64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|arm64">
<Configuration>Release</Configuration>
<Platform>arm64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
<PathToXAMLWinRTImplementations>Contoso.WinUI.Desktop.Demo\</PathToXAMLWinRTImplementations>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<PropertyGroup>
<ProjectGuid>40123b52-ae63-4a0a-8661-3644bede411d</ProjectGuid>
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<AssetTargetFallback>net5.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
<DefaultLanguage>en-US</DefaultLanguage>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\Contoso.WinUI.Desktop.Demo\Contoso.WinUI.Desktop.Demo.csproj</EntryPointProjectUniqueName>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contoso.WinUI.Desktop.Demo\Contoso.WinUI.Desktop.Demo.csproj">
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
<PublishProfile>Properties\PublishProfiles\win10-$(Platform).pubxml</PublishProfile>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ProjectReunion" Version="[0.8.1]">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.ProjectReunion.WinUI" Version="[0.8.1]">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
</Project>

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 432 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 637 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 283 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 456 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Просмотреть файл

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="1351d609-eaaa-44b8-8752-b6bab406bb98"
Publisher="CN=Microsoft.AppCenter"
Version="1.0.0.0" />
<Properties>
<DisplayName>Contoso.WinUI.Desktop.Demo (Package)</DisplayName>
<PublisherDisplayName>Microsoft.AppCenter</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="Contoso.WinUI.Desktop.Demo (Package)"
Description="Contoso.WinUI.Desktop.Demo (Package)"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

Просмотреть файл

@ -0,0 +1,15 @@
<Application
x:Class="Contoso.WinUI.Desktop.Demo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Contoso.WinUI.Desktop.Demo">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>

Просмотреть файл

@ -0,0 +1,147 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.Storage;
using System.Globalization;
using Microsoft.AspNetCore.StaticFiles;
namespace Contoso.WinUI.Desktop.Demo
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : Application
{
private ApplicationDataContainer localSettings;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
// Init settings.
localSettings = ApplicationData.Current.LocalSettings;
TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs args) =>
{
// If you see this message while testing the app and if the stack trace is SDK related, we might have a bug in the SDK as we don't want to leak any exception from the SDK.
AppCenterLog.Error("AppCenterPuppet", "Unobserved exception observed=" + args.Observed, args.Exception);
};
CoreApplication.EnablePrelaunch(true);
InitializeComponent();
AppCenter.LogLevel = LogLevel.Verbose;
// Set data from local storage.
var countryCode = localSettings.Values[Constants.KeyCountryCode] as string;
if (!string.IsNullOrEmpty(countryCode))
{
AppCenter.SetCountryCode(countryCode);
}
var storageSize = localSettings.Values[Constants.KeyStorageMaxSize] as long?;
if (storageSize != null && storageSize > 0)
{
AppCenter.SetMaxStorageSizeAsync((long)storageSize);
}
// User callbacks.
Crashes.ShouldProcessErrorReport = (report) =>
{
Log($"Determining whether to process error report with an ID: {report.Id}");
return true;
};
Crashes.GetErrorAttachments = GetErrorAttachmentsHandler;
// Event handlers.
Crashes.SendingErrorReport += (_, args) => Log($"Sending error report for an error ID: {args.Report.Id}");
Crashes.SentErrorReport += (_, args) => Log($"Sent error report for an error ID: {args.Report.Id}");
Crashes.FailedToSendErrorReport += (_, args) => Log($"Failed to send error report for an error ID: {args.Report.Id}");
// Start App Center.
AppCenter.Start("3af4ebc7-2ecb-47d6-a1cf-155119cb207a", typeof(Analytics), typeof(Crashes));
// Set userId.
var userId = localSettings.Values[Constants.KeyUserId] as string;
if (!string.IsNullOrEmpty(userId))
{
AppCenter.SetUserId(userId);
}
Crashes.HasCrashedInLastSessionAsync().ContinueWith(hasCrashed =>
{
Log("Crashes.HasCrashedInLastSession=" + hasCrashed.Result);
});
Crashes.GetLastSessionCrashReportAsync().ContinueWith(task =>
{
Log("Crashes.LastSessionCrashReport.StackTrace=" + task.Result?.StackTrace);
});
}
private static void Log(string message)
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
System.Diagnostics.Debug.WriteLine($"{timestamp} [AppCenterPuppet] Info: {message}");
}
private static IEnumerable<ErrorAttachmentLog> GetErrorAttachmentsHandler(ErrorReport report)
{
return GetErrorAttachments();
}
public static IEnumerable<ErrorAttachmentLog> GetErrorAttachments()
{
var attachments = new List<ErrorAttachmentLog>();
// Text attachment.
var localSettings = ApplicationData.Current.LocalSettings;
var textAttachments = localSettings.Values[Constants.KeyTextErrorAttachments] as string;
if (!string.IsNullOrEmpty(textAttachments))
{
attachments.Add(ErrorAttachmentLog.AttachmentWithText(textAttachments, "text.txt"));
}
// Binary attachment.
var fileAttachments = localSettings.Values[Constants.KeyFileErrorAttachments] as string;
if (!string.IsNullOrEmpty(fileAttachments))
{
if (File.Exists(fileAttachments))
{
var fileName = new FileInfo(fileAttachments).Name;
var provider = new FileExtensionContentTypeProvider();
if (!provider.TryGetContentType(fileName, out var contentType))
{
contentType = "application/octet-stream";
}
var fileContent = File.ReadAllBytes(fileAttachments);
attachments.Add(ErrorAttachmentLog.AttachmentWithBinary(fileContent, fileName, contentType));
}
else
{
localSettings.Values[Constants.KeyFileErrorAttachments] = null;
}
}
return attachments;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
m_window = new MainWindow();
m_window.Activate();
}
private Window m_window;
}
}

Просмотреть файл

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Contoso.WinUI.Desktop.Demo
{
public class Constants
{
public static string KeyStorageMaxSize = "StorageMaxSize";
public static string KeyUserId = "UserId";
public static string KeyCountryCode = "CountryCode";
public static string KeyFileErrorAttachments = "FileErrorAttachments";
public static string KeyTextErrorAttachments = "TextErrorAttachments";
}
}

Просмотреть файл

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>Contoso.WinUI.Desktop.Demo</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64;arm64</Platforms>
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
<UseWinUI>true</UseWinUI>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AppCenter" Version="4.3.0" />
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="4.3.0" />
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.3.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.ProjectReunion" Version="0.8.1" />
<PackageReference Include="Microsoft.ProjectReunion.Foundation" Version="0.8.1" />
<PackageReference Include="Microsoft.ProjectReunion.WinUI" Version="0.8.1" />
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Contoso.UtilClassLibrary\Contoso.UtilClassLibrary.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,190 @@
<Window
x:Class="Contoso.WinUI.Desktop.Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Contoso.WinUI.Desktop.Demo"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Stretch" Margin="16, 16, 16, 16" Width="Auto">
<muxc:TabView HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionChanged="TabControl_SelectionChanged" IsAddTabButtonVisible="False">
<muxc:TabView.TabItems>
<muxc:TabViewItem Header="App Center" IsClosable="False">
<StackPanel>
<CheckBox Name="AppCenterEnabled" Content="App Center Enabled" Margin="0, 10, 0, 5" Checked="AppCenterEnabled_Checked" Unchecked="AppCenterEnabled_Unchecked"/>
<CheckBox Name="AppCenterAllowNetworkRequests" Content="Allow network requests" Margin="0, 5, 0, 10" Checked="AppCenterAllowNetworkRequests_Checked" Unchecked="AppCenterAllowNetworkRequests_Unchecked"/>
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<!-- Set storage size and userId -->
<StackPanel Orientation ="Vertical" HorizontalAlignment="Left" Margin="0, 16, 0, 16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="User Id" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="UserId" Width="250" Grid.Column="1" Grid.Row="0" Margin="16, 4, 16, 4" KeyDown="UserId_KeyDown" LostFocus="UserId_LostFocus"/>
<TextBlock Text="Storage Max Size" Grid.Column="0" Grid.Row="1"/>
<TextBox Name="StorageMaxSize" Width="250" Grid.Column="1" Grid.Row="1" Margin="16, 4, 16, 4"/>
<Button Name="SaveStorageSize" Click="SaveStorageSize_Click" Content="Save Storage Size" Grid.Column="0" Grid.Row="2" Padding="16,4,16,4"/>
</Grid>
</StackPanel>
<!-- Set country code -->
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<StackPanel Margin="0, 16, 0, 16">
<CheckBox Name="CountryCodeEnableCheckbox" Content="Country Code Enabled" Margin="0, 10, 0, 10" Checked="CountryCodeEnableCheckbox_Checked" Unchecked="CountryCodeEnableCheckbox_Unchecked"/>
<StackPanel Name="CountryCodePanel">
<TextBlock Text="Country code" Name="CountryCodeLabel"/>
<TextBox Name="CountryCodeText" VerticalAlignment="Center"/>
<Button Name="SaveCountryCodeButton" Content="Save" Margin="0, 8, 0, 8" Click="SaveCountryCodeButton_Click"/>
<TextBlock Visibility="Collapsed" Text="Country code has been updated. This value will only be applied to the following sessions." Foreground="Red" Name="CountryCodeNotice" TextWrapping="Wrap"/>
</StackPanel>
</StackPanel>
</StackPanel>
</muxc:TabViewItem>
<muxc:TabViewItem Header="Analytics" IsClosable="False">
<StackPanel>
<CheckBox Name="AnalyticsEnabled" Content="Analytics Enabled" Margin="0,10,0,10" Checked="AnalyticsEnabled_Checked" Unchecked="AnalyticsEnabled_Unchecked"/>
<TextBlock Text="Event Name"/>
<TextBox Name="EventName" VerticalAlignment="Center" />
<!-- Add properties -->
<StackPanel Orientation ="Vertical" HorizontalAlignment="Left" Margin="0, 16, 0, 16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Key" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="EventKeyItem" Width="250" Grid.Column="1" Grid.Row="0" Margin="16, 4, 16, 4" KeyDown="UserId_KeyDown" LostFocus="UserId_LostFocus"/>
<TextBlock Text="Value" Grid.Column="0" Grid.Row="1"/>
<TextBox Name="EventValueItem" Width="250" Grid.Column="1" Grid.Row="1" Margin="16, 4, 16, 4"/>
<Button Name="EventAddProperties" Click="EventAddProperties_Click" Content="Add property" Grid.Column="0" Grid.Row="2" Padding="16,4,16,4"/>
</Grid>
</StackPanel>
<!-- Show selected properties -->
<ListView x:Name="EventProperties" Margin="0,16,0,16" Header="Selected properties" Background="{ThemeResource SystemControlBackgroundListMediumBrush}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Name="EventPropertyKey" Margin="16, 4, 16, 4" TextWrapping="NoWrap" Text="{Binding Key}"/>
<TextBlock Name="EventPropertyValue" Margin="16, 4, 16, 4" TextWrapping="NoWrap" Text="{Binding Value}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Name="TrackEvent" Margin="0, 8, 0, 8" Content="Track event" Click="TrackEvent_Click"/>
</StackPanel>
</muxc:TabViewItem>
<muxc:TabViewItem Header="Crashes" IsClosable="False">
<StackPanel>
<StackPanel>
<CheckBox Name="CrashesEnabled" Content="Crashes Enabled" Margin="0,10,0,10" Checked="CrashesEnabled_Checked" Unchecked="CrashesEnabled_Unchecked" />
<CheckBox Name="HandleExceptions" Content="Handle Exceptions" Margin="0,10,0,10" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Error properties"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<!-- Add properties -->
<StackPanel Orientation ="Vertical" HorizontalAlignment="Left" Margin="0, 16, 0, 16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Key" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="ErrorKeyItem" Width="250" Grid.Column="1" Grid.Row="0" Margin="16, 4, 16, 4" KeyDown="UserId_KeyDown" LostFocus="UserId_LostFocus"/>
<TextBlock Text="Value" Grid.Column="0" Grid.Row="1"/>
<TextBox Name="ErrorValueItem" Width="250" Grid.Column="1" Grid.Row="1" Margin="16, 4, 16, 4"/>
<Button Name="CrashesAddProperties" Click="CrashesAddNewProperty_Click" Content="Add property" Grid.Column="0" Grid.Row="2" Padding="16,4,16,4"/>
</Grid>
</StackPanel>
<!-- Show selected properties -->
<ListView x:Name="ErrorProperties" Margin="0,16,0,16" Header="Selected properties" Background="{ThemeResource SystemControlBackgroundListMediumBrush}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Name="CrashesPropertyKey" Margin="16, 4, 16, 4" TextWrapping="NoWrap" Text="{Binding Key}"/>
<TextBlock Name="CrashesPropertyValue" Margin="16, 4, 16, 4" TextWrapping="NoWrap" Text="{Binding Value}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- Select error attachments -->
<StackPanel Orientation="Horizontal">
<TextBlock Text="Error attachments"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<StackPanel Orientation ="Vertical" HorizontalAlignment="Left" Margin="0, 16, 0, 16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Text attachment" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="TextAttachmentTextBox" TextChanged="TextAttachmentTextBox_TextChanged" VerticalAlignment="Center" Grid.Column="1" Grid.Row="0" Margin="16, 4, 16, 4" />
<TextBlock Text="File attachment" Grid.Column="0" Grid.Row="1"/>
<TextBlock Name="FileAttachmentLabel" Margin="16, 4, 16, 4" Text="The file isn't selected" Width="250" Grid.Column="1" Grid.Row="1" />
<Button Name="SaveAttachments" Click="FileErrorAttachment_Click" Content="Select file attachment" Grid.Column="0" Grid.Row="2" Padding="16, 4, 16, 4"/>
</Grid>
</StackPanel>
<!-- Test crashes -->
<StackPanel Orientation="Horizontal">
<TextBlock Text="Crashes"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<StackPanel Margin="0, 8, 0, 8" Orientation="Vertical">
<Button Content="Call Crashes.GenerateTestCrash (debug only)" Margin="2" Click="CrashWithTestException_Click"/>
<Button Content="Generate non serializable Exception" Margin="2" Click="CrashWithNonSerializableException_Click" />
<Button Content="Divide by zero" Margin="2" Click="CrashWithDivisionByZero_Click" />
<Button Content="Aggregate Exception" Margin="2" Click="CrashWithAggregateException_Click" />
<Button Content="Crash with null reference" Margin="2" Click="CrashWithNullReference_Click"/>
<Button Content="Async task crash" Margin="2" Click="CrashInsideAsyncTask_Click"/>
</StackPanel>
</StackPanel>
</StackPanel>
</muxc:TabViewItem>
</muxc:TabView.TabItems>
</muxc:TabView>
</StackPanel>
</Window>

Просмотреть файл

@ -0,0 +1,442 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using System;
using System.IO;
using System.Linq;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using Windows.Storage;
using Windows.Storage.Pickers;
using System.Threading.Tasks;
using System.Globalization;
using System.Collections.ObjectModel;
using Contoso.UtilClassLibrary;
using System.Runtime.InteropServices;
using WinRT;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace Contoso.WinUI.Desktop.Demo
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainWindow : Window
{
private string fileAttachments;
private string textAttachments;
private ObservableCollection<Property> EventPropertiesSource = new ObservableCollection<Property>();
private ObservableCollection<Property> ErrorPropertiesSource = new ObservableCollection<Property>();
private ApplicationDataContainer localSettings;
public MainWindow()
{
this.InitializeComponent();
localSettings = ApplicationData.Current.LocalSettings;
UpdateState();
EventProperties.ItemsSource = EventPropertiesSource;
ErrorProperties.ItemsSource = ErrorPropertiesSource;
fileAttachments = localSettings.Values[Constants.KeyFileErrorAttachments] as string;
textAttachments = localSettings.Values[Constants.KeyTextErrorAttachments] as string;
TextAttachmentTextBox.Text = textAttachments;
FileAttachmentLabel.Text = fileAttachments ?? "The file isn't selected";
var countryCode = localSettings.Values[Constants.KeyCountryCode] as string;
if (!string.IsNullOrEmpty(countryCode))
{
CountryCodeEnableCheckbox.IsChecked = true;
CountryCodeText.Text = countryCode;
}
var userId = localSettings.Values[Constants.KeyUserId] as string;
if (!string.IsNullOrEmpty(userId))
{
UserId.Text = userId;
}
var storageSize = localSettings.Values[Constants.KeyStorageMaxSize] as long?;
if (storageSize != null && storageSize > 0)
{
StorageMaxSize.Text = storageSize.ToString();
}
}
private void UpdateState()
{
AppCenterEnabled.IsChecked = AppCenter.IsEnabledAsync().Result;
AppCenterAllowNetworkRequests.IsChecked = AppCenter.IsNetworkRequestsAllowed;
CrashesEnabled.IsChecked = Crashes.IsEnabledAsync().Result;
AnalyticsEnabled.IsChecked = Analytics.IsEnabledAsync().Result;
AnalyticsEnabled.IsEnabled = AppCenterEnabled.IsChecked.Value;
CrashesEnabled.IsEnabled = AppCenterEnabled.IsChecked.Value;
}
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
UpdateState();
}
#region AppCenter
private void AppCenterAllowNetworkRequests_Unchecked(object sender, RoutedEventArgs e)
{
HandleAllowNetworkRequest();
}
private void AppCenterAllowNetworkRequests_Checked(object sender, RoutedEventArgs e)
{
HandleAllowNetworkRequest();
}
private void HandleAllowNetworkRequest()
{
if (AppCenterAllowNetworkRequests.IsChecked.HasValue)
{
AppCenter.IsNetworkRequestsAllowed = AppCenterAllowNetworkRequests.IsChecked.Value;
}
}
private void AppCenterEnabled_Checked(object sender, RoutedEventArgs e)
{
HandleAppCenterEnabled();
}
private void AppCenterEnabled_Unchecked(object sender, RoutedEventArgs e)
{
HandleAppCenterEnabled();
}
private void HandleAppCenterEnabled()
{
if (AppCenterEnabled.IsChecked.HasValue)
{
AppCenter.SetEnabledAsync(AppCenterEnabled.IsChecked.Value).Wait();
}
}
private void CountryCodeEnableCheckbox_Unchecked(object sender, RoutedEventArgs e)
{
HandleCountryCodeEnabled();
}
private void CountryCodeEnableCheckbox_Checked(object sender, RoutedEventArgs e)
{
HandleCountryCodeEnabled();
}
private void HandleCountryCodeEnabled()
{
if (!CountryCodeEnableCheckbox.IsChecked.HasValue)
{
return;
}
if (!CountryCodeEnableCheckbox.IsChecked.Value)
{
CountryCodeText.Text = "";
SaveCountryCode();
}
else
{
if (string.IsNullOrEmpty(localSettings.Values[Constants.KeyCountryCode] as string))
{
CountryCodeText.Text = RegionInfo.CurrentRegion.TwoLetterISORegionName;
}
else
{
CountryCodeText.Text = localSettings.Values[Constants.KeyCountryCode] as string;
}
}
}
private void SaveCountryCodeButton_Click(object sender, RoutedEventArgs e)
{
SaveCountryCode();
}
private void SaveCountryCode()
{
CountryCodeNotice.Visibility = Visibility.Visible;
localSettings.Values[Constants.KeyCountryCode] = CountryCodeText.Text;
AppCenter.SetCountryCode(CountryCodeText.Text.Length > 0 ? CountryCodeText.Text : null);
}
private void SaveStorageSize_Click(object sender, RoutedEventArgs e)
{
var storageSize = StorageMaxSize.Text;
var size = 10L * 1024 * 1024;
long.TryParse(storageSize, out size);
AppCenter.SetMaxStorageSizeAsync(size);
localSettings.Values[Constants.KeyStorageMaxSize] = size;
}
private void UserId_LostFocus(object sender, RoutedEventArgs e)
{
HandleUserIdChange();
}
private void UserId_KeyDown(object sender, KeyRoutedEventArgs e)
{
HandleUserIdChange();
}
private void HandleUserIdChange()
{
var userId = UserId.Text;
var text = string.IsNullOrEmpty(userId) ? null : userId;
AppCenter.SetUserId(text);
localSettings.Values[Constants.KeyUserId] = text;
}
#endregion
#region Analytics
private void AnalyticsEnabled_Checked(object sender, RoutedEventArgs e)
{
HandleAnalyticsEnabled();
}
private void AnalyticsEnabled_Unchecked(object sender, RoutedEventArgs e)
{
HandleAnalyticsEnabled();
}
private void HandleAnalyticsEnabled()
{
AnalyticsEnabled.IsEnabled = AppCenterEnabled.IsChecked.Value;
Analytics.SetEnabledAsync(AnalyticsEnabled.IsChecked.Value).Wait();
}
private void TrackEvent_Click(object sender, RoutedEventArgs e)
{
var name = EventName.Text;
var propertiesDictionary = EventPropertiesSource.Where(property => property.Key != null && property.Value != null)
.ToDictionary(property => property.Key, property => property.Value);
Analytics.TrackEvent(name, propertiesDictionary);
EventPropertiesSource.Clear();
}
private void EventAddProperties_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(EventKeyItem.Text) || string.IsNullOrEmpty(EventValueItem.Text))
{
return;
}
var property = new Property();
property.Key = EventKeyItem.Text;
property.Value = EventValueItem.Text;
EventKeyItem.Text = "";
EventValueItem.Text = "";
EventPropertiesSource.Add(property);
}
#endregion
#region Crash
private void CrashesEnabled_Checked(object sender, RoutedEventArgs e)
{
HandleCrashesEnabled();
}
private void CrashesEnabled_Unchecked(object sender, RoutedEventArgs e)
{
HandleCrashesEnabled();
}
private void HandleCrashesEnabled()
{
CrashesEnabled.IsEnabled = AppCenterEnabled.IsChecked.Value;
Crashes.SetEnabledAsync(CrashesEnabled.IsChecked.Value).Wait();
}
public class NonSerializableException : Exception
{
}
private void CrashWithTestException_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() => Crashes.GenerateTestCrash());
ErrorPropertiesSource.Clear();
}
private void CrashWithNonSerializableException_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() => throw new NonSerializableException());
ErrorPropertiesSource.Clear();
}
private void CrashWithDivisionByZero_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() => { _ = 42 / int.Parse("0"); });
ErrorPropertiesSource.Clear();
}
private void CrashWithAggregateException_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() => throw GenerateAggregateException());
ErrorPropertiesSource.Clear();
}
private static Exception GenerateAggregateException()
{
try
{
throw new AggregateException(SendHttp(), new ArgumentException("Invalid parameter", ValidateLength()));
}
catch (Exception e)
{
return e;
}
}
private static Exception SendHttp()
{
try
{
throw new IOException("Network down");
}
catch (Exception e)
{
return e;
}
}
private static Exception ValidateLength()
{
try
{
throw new ArgumentOutOfRangeException(null, "It's over 9000!");
}
catch (Exception e)
{
return e;
}
}
private void CrashWithNullReference_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() =>
{
string[] values = { "a", null, "c" };
var b = values[1].Trim();
System.Diagnostics.Debug.WriteLine(b);
});
ErrorPropertiesSource.Clear();
}
private async void CrashInsideAsyncTask_Click(object sender, RoutedEventArgs e)
{
try
{
await FakeService.DoStuffInBackground();
}
catch (Exception ex) when (HandleExceptions.IsChecked.Value)
{
TrackException(ex);
}
ErrorPropertiesSource.Clear();
}
private void ClassLibraryException_Click(object sender, RoutedEventArgs e)
{
CrashUtils.BackgroundExceptionTask().RunSynchronously();
}
private static class FakeService
{
public static async Task DoStuffInBackground()
{
await Task.Run(() => throw new IOException("Server did not respond"));
}
}
private void TrackException(Exception e)
{
var properties = ErrorPropertiesSource.Where(property => property.Key != null && property.Value != null).ToDictionary(property => property.Key, property => property.Value);
if (properties.Count == 0)
{
properties = null;
}
Crashes.TrackError(e, properties, App.GetErrorAttachments().ToArray());
ErrorPropertiesSource.Clear();
}
void HandleOrThrow(Action action)
{
try
{
action();
}
catch (Exception e) when (HandleExceptions.IsChecked.Value)
{
TrackException(e);
}
ErrorPropertiesSource.Clear();
}
private void TextAttachmentTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
textAttachments = TextAttachmentTextBox.Text;
localSettings.Values[Constants.KeyTextErrorAttachments] = textAttachments;
}
private async void FileErrorAttachment_Click(object sender, RoutedEventArgs e)
{
// Open a text file.
FileOpenPicker open = new FileOpenPicker();
open.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
open.FileTypeFilter.Add("*");
// When running on win32, FileOpenPicker needs to know the top-level hwnd via IInitializeWithWindow::Initialize.
if (Window.Current == null)
{
IInitializeWithWindow initializeWithWindowWrapper = open.As<IInitializeWithWindow>();
IntPtr hwnd = GetActiveWindow();
initializeWithWindowWrapper.Initialize(hwnd);
}
StorageFile file = await open.PickSingleFileAsync();
var filePath = string.Empty;
if (file != null)
{
filePath = file.Path;
FileAttachmentLabel.Text = filePath;
}
else
{
FileAttachmentLabel.Text = "The file isn't selected";
}
localSettings.Values[Constants.KeyFileErrorAttachments] = filePath;
}
private void CrashesAddNewProperty_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(ErrorKeyItem.Text) || string.IsNullOrEmpty(ErrorValueItem.Text))
{
return;
}
var property = new Property();
property.Key = ErrorKeyItem.Text;
property.Value = ErrorValueItem.Text;
ErrorKeyItem.Text = "";
ErrorValueItem.Text = "";
ErrorPropertiesSource.Add(property);
}
#endregion
[ComImport, Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInitializeWithWindow
{
void Initialize([In] IntPtr hwnd);
}
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto, PreserveSig = true, SetLastError = false)]
public static extern IntPtr GetActiveWindow();
}
}

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>arm64</Platform>
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>True</PublishReadyToRun>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>x64</Platform>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>True</PublishReadyToRun>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>x86</Platform>
<RuntimeIdentifier>win10-x86</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>True</PublishReadyToRun>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Contoso.WinUI.Desktop.Demo
{
class Property : INotifyPropertyChanged
{
private string _key;
private string _value;
public string Key
{
get
{
return _key;
}
set
{
if (_key != value)
{
_key = value;
NotifyPropertyChanged();
}
}
}
public string Value
{
get
{
return _value;
}
set
{
if (_value != value)
{
_value = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="Contoso.WinUI.Desktop.Demo.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</windowsSettings>
</application>
</assembly>

Просмотреть файл

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'">
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|arm64">
<Configuration>Debug</Configuration>
<Platform>arm64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|arm64">
<Configuration>Release</Configuration>
<Platform>arm64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
<PathToXAMLWinRTImplementations>Contoso.WinUI.Desktop.Puppet\</PathToXAMLWinRTImplementations>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<PropertyGroup>
<ProjectGuid>345565c8-4971-4d1a-88cc-f7cbdae2c7c7</ProjectGuid>
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<AssetTargetFallback>net5.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
<DefaultLanguage>en-US</DefaultLanguage>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\Contoso.WinUI.Desktop.Puppet\Contoso.WinUI.Desktop.Puppet.csproj</EntryPointProjectUniqueName>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contoso.WinUI.Desktop.Puppet\Contoso.WinUI.Desktop.Puppet.csproj">
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
<PublishProfile>Properties\PublishProfiles\win10-$(Platform).pubxml</PublishProfile>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ProjectReunion" Version="[0.8.1]">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.ProjectReunion.WinUI" Version="[0.8.1]">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
</Project>

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 432 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 637 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 283 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 456 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Просмотреть файл

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="796335c7-b33b-483b-995f-fa87ae20db4f"
Publisher="CN=Microsoft.AppCenter"
Version="1.0.0.0" />
<Properties>
<DisplayName>Contoso.WinUI.Desktop.Puppet (Package)</DisplayName>
<PublisherDisplayName>Microsoft.AppCenter</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="Contoso.WinUI.Desktop.Puppet (Package)"
Description="Contoso.WinUI.Desktop.Puppet (Package)"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

Просмотреть файл

@ -0,0 +1,15 @@
<Application
x:Class="Contoso.WinUI.Desktop.Puppet.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Contoso.WinUI.Desktop.Puppet">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>

Просмотреть файл

@ -0,0 +1,148 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.Storage;
using System.Globalization;
using Microsoft.AspNetCore.StaticFiles;
namespace Contoso.WinUI.Desktop.Puppet
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : Application
{
private ApplicationDataContainer localSettings;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
// Init settings.
localSettings = ApplicationData.Current.LocalSettings;
TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs args) =>
{
// If you see this message while testing the app and if the stack trace is SDK related, we might have a bug in the SDK as we don't want to leak any exception from the SDK.
AppCenterLog.Error("AppCenterPuppet", "Unobserved exception observed=" + args.Observed, args.Exception);
};
CoreApplication.EnablePrelaunch(true);
InitializeComponent();
AppCenter.LogLevel = LogLevel.Verbose;
AppCenter.SetLogUrl("https://in-integration.dev.avalanch.es");
// Set data from local storage.
var countryCode = localSettings.Values[Constants.KeyCountryCode] as string;
if (!string.IsNullOrEmpty(countryCode))
{
AppCenter.SetCountryCode(countryCode);
}
var storageSize = localSettings.Values[Constants.KeyStorageMaxSize] as long?;
if (storageSize != null && storageSize > 0)
{
AppCenter.SetMaxStorageSizeAsync((long)storageSize);
}
// User callbacks.
Crashes.ShouldProcessErrorReport = (report) =>
{
Log($"Determining whether to process error report with an ID: {report.Id}");
return true;
};
Crashes.GetErrorAttachments = GetErrorAttachmentsHandler;
// Event handlers.
Crashes.SendingErrorReport += (_, args) => Log($"Sending error report for an error ID: {args.Report.Id}");
Crashes.SentErrorReport += (_, args) => Log($"Sent error report for an error ID: {args.Report.Id}");
Crashes.FailedToSendErrorReport += (_, args) => Log($"Failed to send error report for an error ID: {args.Report.Id}");
// Start App Center.
AppCenter.Start("2daf2955-b4e4-4206-b38a-fedcdc6f4f84", typeof(Analytics), typeof(Crashes));
// Set userId.
var userId = localSettings.Values[Constants.KeyUserId] as string;
if (!string.IsNullOrEmpty(userId))
{
AppCenter.SetUserId(userId);
}
Crashes.HasCrashedInLastSessionAsync().ContinueWith(hasCrashed =>
{
Log("Crashes.HasCrashedInLastSession=" + hasCrashed.Result);
});
Crashes.GetLastSessionCrashReportAsync().ContinueWith(task =>
{
Log("Crashes.LastSessionCrashReport.StackTrace=" + task.Result?.StackTrace);
});
}
private static void Log(string message)
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
System.Diagnostics.Debug.WriteLine($"{timestamp} [AppCenterPuppet] Info: {message}");
}
private static IEnumerable<ErrorAttachmentLog> GetErrorAttachmentsHandler(ErrorReport report)
{
return GetErrorAttachments();
}
public static IEnumerable<ErrorAttachmentLog> GetErrorAttachments()
{
var attachments = new List<ErrorAttachmentLog>();
// Text attachment.
var localSettings = ApplicationData.Current.LocalSettings;
var textAttachments = localSettings.Values[Constants.KeyTextErrorAttachments] as string;
if (!string.IsNullOrEmpty(textAttachments))
{
attachments.Add(ErrorAttachmentLog.AttachmentWithText(textAttachments, "text.txt"));
}
// Binary attachment.
var fileAttachments = localSettings.Values[Constants.KeyFileErrorAttachments] as string;
if (!string.IsNullOrEmpty(fileAttachments))
{
if (File.Exists(fileAttachments))
{
var fileName = new FileInfo(fileAttachments).Name;
var provider = new FileExtensionContentTypeProvider();
if (!provider.TryGetContentType(fileName, out var contentType))
{
contentType = "application/octet-stream";
}
var fileContent = File.ReadAllBytes(fileAttachments);
attachments.Add(ErrorAttachmentLog.AttachmentWithBinary(fileContent, fileName, contentType));
}
else
{
localSettings.Values[Constants.KeyFileErrorAttachments] = null;
}
}
return attachments;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
m_window = new MainWindow();
m_window.Activate();
}
private Window m_window;
}
}

Просмотреть файл

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Contoso.WinUI.Desktop.Puppet
{
public class Constants
{
public static string KeyStorageMaxSize = "StorageMaxSize";
public static string KeyUserId = "UserId";
public static string KeyCountryCode = "CountryCode";
public static string KeyFileErrorAttachments = "FileErrorAttachments";
public static string KeyTextErrorAttachments = "TextErrorAttachments";
}
}

Просмотреть файл

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<RootNamespace>Contoso.WinUI.Desktop.Puppet</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64</Platforms>
<RuntimeIdentifiers>win10-x86;win10-x64</RuntimeIdentifiers>
<UseWinUI>true</UseWinUI>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.ProjectReunion" Version="0.8.1" />
<PackageReference Include="Microsoft.ProjectReunion.Foundation" Version="0.8.1" />
<PackageReference Include="Microsoft.ProjectReunion.WinUI" Version="0.8.1" />
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\SDK\AppCenterAnalytics\Microsoft.AppCenter.Analytics.WindowsDesktop\Microsoft.AppCenter.Analytics.WindowsDesktop.csproj" />
<ProjectReference Include="..\..\..\SDK\AppCenterCrashes\Microsoft.AppCenter.Crashes.WindowsDesktop\Microsoft.AppCenter.Crashes.WindowsDesktop.csproj" />
<ProjectReference Include="..\..\..\SDK\AppCenter\Microsoft.AppCenter.WindowsDesktop\Microsoft.AppCenter.WindowsDesktop.csproj" />
<ProjectReference Include="..\..\Contoso.UtilClassLibrary\Contoso.UtilClassLibrary.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,190 @@
<Window
x:Class="Contoso.WinUI.Desktop.Puppet.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Contoso.WinUI.Desktop.Puppet"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Stretch" Margin="16, 16, 16, 16" Width="Auto">
<muxc:TabView HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionChanged="TabControl_SelectionChanged" IsAddTabButtonVisible="False">
<muxc:TabView.TabItems>
<muxc:TabViewItem Header="App Center" IsClosable="False">
<StackPanel>
<CheckBox Name="AppCenterEnabled" Content="App Center Enabled" Margin="0, 10, 0, 5" Checked="AppCenterEnabled_Checked" Unchecked="AppCenterEnabled_Unchecked"/>
<CheckBox Name="AppCenterAllowNetworkRequests" Content="Allow network requests" Margin="0, 5, 0, 10" Checked="AppCenterAllowNetworkRequests_Checked" Unchecked="AppCenterAllowNetworkRequests_Unchecked"/>
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<!-- Set storage size and userId -->
<StackPanel Orientation ="Vertical" HorizontalAlignment="Left" Margin="0, 16, 0, 16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="User Id" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="UserId" Width="250" Grid.Column="1" Grid.Row="0" Margin="16, 4, 16, 4" KeyDown="UserId_KeyDown" LostFocus="UserId_LostFocus"/>
<TextBlock Text="Storage Max Size" Grid.Column="0" Grid.Row="1"/>
<TextBox Name="StorageMaxSize" Width="250" Grid.Column="1" Grid.Row="1" Margin="16, 4, 16, 4"/>
<Button Name="SaveStorageSize" Click="SaveStorageSize_Click" Content="Save Storage Size" Grid.Column="0" Grid.Row="2" Padding="16,4,16,4"/>
</Grid>
</StackPanel>
<!-- Set country code -->
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<StackPanel Margin="0, 16, 0, 16">
<CheckBox Name="CountryCodeEnableCheckbox" Content="Country Code Enabled" Margin="0, 10, 0, 10" Checked="CountryCodeEnableCheckbox_Checked" Unchecked="CountryCodeEnableCheckbox_Unchecked"/>
<StackPanel Name="CountryCodePanel">
<TextBlock Text="Country code" Name="CountryCodeLabel"/>
<TextBox Name="CountryCodeText" VerticalAlignment="Center"/>
<Button Name="SaveCountryCodeButton" Content="Save" Margin="0, 8, 0, 8" Click="SaveCountryCodeButton_Click"/>
<TextBlock Visibility="Collapsed" Text="Country code has been updated. This value will only be applied to the following sessions." Foreground="Red" Name="CountryCodeNotice" TextWrapping="Wrap"/>
</StackPanel>
</StackPanel>
</StackPanel>
</muxc:TabViewItem>
<muxc:TabViewItem Header="Analytics" IsClosable="False">
<StackPanel>
<CheckBox Name="AnalyticsEnabled" Content="Analytics Enabled" Margin="0,10,0,10" Checked="AnalyticsEnabled_Checked" Unchecked="AnalyticsEnabled_Unchecked"/>
<TextBlock Text="Event Name"/>
<TextBox Name="EventName" VerticalAlignment="Center" />
<!-- Add properties -->
<StackPanel Orientation ="Vertical" HorizontalAlignment="Left" Margin="0, 16, 0, 16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Key" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="EventKeyItem" Width="250" Grid.Column="1" Grid.Row="0" Margin="16, 4, 16, 4" KeyDown="UserId_KeyDown" LostFocus="UserId_LostFocus"/>
<TextBlock Text="Value" Grid.Column="0" Grid.Row="1"/>
<TextBox Name="EventValueItem" Width="250" Grid.Column="1" Grid.Row="1" Margin="16, 4, 16, 4"/>
<Button Name="EventAddProperties" Click="EventAddProperties_Click" Content="Add property" Grid.Column="0" Grid.Row="2" Padding="16,4,16,4"/>
</Grid>
</StackPanel>
<!-- Show selected properties -->
<ListView x:Name="EventProperties" Margin="0,16,0,16" Header="Selected properties" Background="{ThemeResource SystemControlBackgroundListMediumBrush}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Name="EventPropertyKey" Margin="16, 4, 16, 4" TextWrapping="NoWrap" Text="{Binding Key}"/>
<TextBlock Name="EventPropertyValue" Margin="16, 4, 16, 4" TextWrapping="NoWrap" Text="{Binding Value}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Name="TrackEvent" Margin="0, 8, 0, 8" Content="Track event" Click="TrackEvent_Click"/>
</StackPanel>
</muxc:TabViewItem>
<muxc:TabViewItem Header="Crashes" IsClosable="False">
<StackPanel>
<StackPanel>
<CheckBox Name="CrashesEnabled" Content="Crashes Enabled" Margin="0,10,0,10" Checked="CrashesEnabled_Checked" Unchecked="CrashesEnabled_Unchecked" />
<CheckBox Name="HandleExceptions" Content="Handle Exceptions" Margin="0,10,0,10" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Error properties"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<!-- Add properties -->
<StackPanel Orientation ="Vertical" HorizontalAlignment="Left" Margin="0, 16, 0, 16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Key" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="ErrorKeyItem" Width="250" Grid.Column="1" Grid.Row="0" Margin="16, 4, 16, 4" KeyDown="UserId_KeyDown" LostFocus="UserId_LostFocus"/>
<TextBlock Text="Value" Grid.Column="0" Grid.Row="1"/>
<TextBox Name="ErrorValueItem" Width="250" Grid.Column="1" Grid.Row="1" Margin="16, 4, 16, 4"/>
<Button Name="CrashesAddProperties" Click="CrashesAddNewProperty_Click" Content="Add property" Grid.Column="0" Grid.Row="2" Padding="16,4,16,4"/>
</Grid>
</StackPanel>
<!-- Show selected properties -->
<ListView x:Name="ErrorProperties" Margin="0,16,0,16" Header="Selected properties" Background="{ThemeResource SystemControlBackgroundListMediumBrush}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Name="CrashesPropertyKey" Margin="16, 4, 16, 4" TextWrapping="NoWrap" Text="{Binding Key}"/>
<TextBlock Name="CrashesPropertyValue" Margin="16, 4, 16, 4" TextWrapping="NoWrap" Text="{Binding Value}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- Select error attachments -->
<StackPanel Orientation="Horizontal">
<TextBlock Text="Error attachments"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<StackPanel Orientation ="Vertical" HorizontalAlignment="Left" Margin="0, 16, 0, 16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Text attachment" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="TextAttachmentTextBox" TextChanged="TextAttachmentTextBox_TextChanged" VerticalAlignment="Center" Grid.Column="1" Grid.Row="0" Margin="16, 4, 16, 4" />
<TextBlock Text="File attachment" Grid.Column="0" Grid.Row="1"/>
<TextBlock Name="FileAttachmentLabel" Margin="16, 4, 16, 4" Text="The file isn't selected" Width="250" Grid.Column="1" Grid.Row="1" />
<Button Name="SaveAttachments" Click="FileErrorAttachment_Click" Content="Select file attachment" Grid.Column="0" Grid.Row="2" Padding="16, 4, 16, 4"/>
</Grid>
</StackPanel>
<!-- Test crashes -->
<StackPanel Orientation="Horizontal">
<TextBlock Text="Crashes"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="1" Background="Gray"/>
<StackPanel Margin="0, 8, 0, 8" Orientation="Vertical">
<Button Content="Call Crashes.GenerateTestCrash (debug only)" Margin="2" Click="CrashWithTestException_Click"/>
<Button Content="Generate non serializable Exception" Margin="2" Click="CrashWithNonSerializableException_Click" />
<Button Content="Divide by zero" Margin="2" Click="CrashWithDivisionByZero_Click" />
<Button Content="Aggregate Exception" Margin="2" Click="CrashWithAggregateException_Click" />
<Button Content="Crash with null reference" Margin="2" Click="CrashWithNullReference_Click"/>
<Button Content="Async task crash" Margin="2" Click="CrashInsideAsyncTask_Click"/>
</StackPanel>
</StackPanel>
</StackPanel>
</muxc:TabViewItem>
</muxc:TabView.TabItems>
</muxc:TabView>
</StackPanel>
</Window>

Просмотреть файл

@ -0,0 +1,443 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using Windows.Storage;
using Windows.Storage.Pickers;
using System.Threading.Tasks;
using System.Globalization;
using System.Collections.ObjectModel;
using Contoso.UtilClassLibrary;
using System.Runtime.InteropServices;
using WinRT;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace Contoso.WinUI.Desktop.Puppet
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainWindow : Window
{
private string fileAttachments;
private string textAttachments;
private ObservableCollection<Property> EventPropertiesSource = new ObservableCollection<Property>();
private ObservableCollection<Property> ErrorPropertiesSource = new ObservableCollection<Property>();
private ApplicationDataContainer localSettings;
public MainWindow()
{
this.InitializeComponent();
localSettings = ApplicationData.Current.LocalSettings;
UpdateState();
EventProperties.ItemsSource = EventPropertiesSource;
ErrorProperties.ItemsSource = ErrorPropertiesSource;
fileAttachments = localSettings.Values[Constants.KeyFileErrorAttachments] as string;
textAttachments = localSettings.Values[Constants.KeyTextErrorAttachments] as string;
TextAttachmentTextBox.Text = textAttachments;
FileAttachmentLabel.Text = fileAttachments ?? "The file isn't selected";
var countryCode = localSettings.Values[Constants.KeyCountryCode] as string;
if (!string.IsNullOrEmpty(countryCode))
{
CountryCodeEnableCheckbox.IsChecked = true;
CountryCodeText.Text = countryCode;
}
var userId = localSettings.Values[Constants.KeyUserId] as string;
if (!string.IsNullOrEmpty(userId))
{
UserId.Text = userId;
}
var storageSize = localSettings.Values[Constants.KeyStorageMaxSize] as long?;
if (storageSize != null && storageSize > 0)
{
StorageMaxSize.Text = storageSize.ToString();
}
}
private void UpdateState()
{
AppCenterEnabled.IsChecked = AppCenter.IsEnabledAsync().Result;
AppCenterAllowNetworkRequests.IsChecked = AppCenter.IsNetworkRequestsAllowed;
CrashesEnabled.IsChecked = Crashes.IsEnabledAsync().Result;
AnalyticsEnabled.IsChecked = Analytics.IsEnabledAsync().Result;
AnalyticsEnabled.IsEnabled = AppCenterEnabled.IsChecked.Value;
CrashesEnabled.IsEnabled = AppCenterEnabled.IsChecked.Value;
}
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
UpdateState();
}
#region AppCenter
private void AppCenterAllowNetworkRequests_Unchecked(object sender, RoutedEventArgs e)
{
HandleAllowNetworkRequest();
}
private void AppCenterAllowNetworkRequests_Checked(object sender, RoutedEventArgs e)
{
HandleAllowNetworkRequest();
}
private void HandleAllowNetworkRequest()
{
if (AppCenterAllowNetworkRequests.IsChecked.HasValue)
{
AppCenter.IsNetworkRequestsAllowed = AppCenterAllowNetworkRequests.IsChecked.Value;
}
}
private void AppCenterEnabled_Checked(object sender, RoutedEventArgs e)
{
HandleAppCenterEnabled();
}
private void AppCenterEnabled_Unchecked(object sender, RoutedEventArgs e)
{
HandleAppCenterEnabled();
}
private void HandleAppCenterEnabled()
{
if (AppCenterEnabled.IsChecked.HasValue)
{
AppCenter.SetEnabledAsync(AppCenterEnabled.IsChecked.Value).Wait();
}
}
private void CountryCodeEnableCheckbox_Unchecked(object sender, RoutedEventArgs e)
{
HandleCountryCodeEnabled();
}
private void CountryCodeEnableCheckbox_Checked(object sender, RoutedEventArgs e)
{
HandleCountryCodeEnabled();
}
private void HandleCountryCodeEnabled()
{
if (!CountryCodeEnableCheckbox.IsChecked.HasValue)
{
return;
}
if (!CountryCodeEnableCheckbox.IsChecked.Value)
{
CountryCodeText.Text = "";
SaveCountryCode();
}
else
{
if (string.IsNullOrEmpty(localSettings.Values[Constants.KeyCountryCode] as string))
{
CountryCodeText.Text = RegionInfo.CurrentRegion.TwoLetterISORegionName;
}
else
{
CountryCodeText.Text = localSettings.Values[Constants.KeyCountryCode] as string;
}
}
}
private void SaveCountryCodeButton_Click(object sender, RoutedEventArgs e)
{
SaveCountryCode();
}
private void SaveCountryCode()
{
CountryCodeNotice.Visibility = Visibility.Visible;
localSettings.Values[Constants.KeyCountryCode] = CountryCodeText.Text;
AppCenter.SetCountryCode(CountryCodeText.Text.Length > 0 ? CountryCodeText.Text : null);
}
private void SaveStorageSize_Click(object sender, RoutedEventArgs e)
{
var storageSize = StorageMaxSize.Text;
var size = 10L * 1024 * 1024;
long.TryParse(storageSize, out size);
AppCenter.SetMaxStorageSizeAsync(size);
localSettings.Values[Constants.KeyStorageMaxSize] = size;
}
private void UserId_LostFocus(object sender, RoutedEventArgs e)
{
HandleUserIdChange();
}
private void UserId_KeyDown(object sender, KeyRoutedEventArgs e)
{
HandleUserIdChange();
}
private void HandleUserIdChange()
{
var userId = UserId.Text;
var text = string.IsNullOrEmpty(userId) ? null : userId;
AppCenter.SetUserId(text);
localSettings.Values[Constants.KeyUserId] = text;
}
#endregion
#region Analytics
private void AnalyticsEnabled_Checked(object sender, RoutedEventArgs e)
{
HandleAnalyticsEnabled();
}
private void AnalyticsEnabled_Unchecked(object sender, RoutedEventArgs e)
{
HandleAnalyticsEnabled();
}
private void HandleAnalyticsEnabled()
{
AnalyticsEnabled.IsEnabled = AppCenterEnabled.IsChecked.Value;
Analytics.SetEnabledAsync(AnalyticsEnabled.IsChecked.Value).Wait();
}
private void TrackEvent_Click(object sender, RoutedEventArgs e)
{
var name = EventName.Text;
var propertiesDictionary = EventPropertiesSource.Where(property => property.Key != null && property.Value != null)
.ToDictionary(property => property.Key, property => property.Value);
Analytics.TrackEvent(name, propertiesDictionary);
EventPropertiesSource.Clear();
}
private void EventAddProperties_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(EventKeyItem.Text) || string.IsNullOrEmpty(EventValueItem.Text))
{
return;
}
var property = new Property();
property.Key = EventKeyItem.Text;
property.Value = EventValueItem.Text;
EventKeyItem.Text = "";
EventValueItem.Text = "";
EventPropertiesSource.Add(property);
}
#endregion
#region Crash
private void CrashesEnabled_Checked(object sender, RoutedEventArgs e)
{
HandleCrashesEnabled();
}
private void CrashesEnabled_Unchecked(object sender, RoutedEventArgs e)
{
HandleCrashesEnabled();
}
private void HandleCrashesEnabled()
{
CrashesEnabled.IsEnabled = AppCenterEnabled.IsChecked.Value;
Crashes.SetEnabledAsync(CrashesEnabled.IsChecked.Value).Wait();
}
public class NonSerializableException : Exception
{
}
private void CrashWithTestException_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() => Crashes.GenerateTestCrash());
ErrorPropertiesSource.Clear();
}
private void CrashWithNonSerializableException_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() => throw new NonSerializableException());
ErrorPropertiesSource.Clear();
}
private void CrashWithDivisionByZero_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() => { _ = 42 / int.Parse("0"); });
ErrorPropertiesSource.Clear();
}
private void CrashWithAggregateException_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() => throw GenerateAggregateException());
ErrorPropertiesSource.Clear();
}
private static Exception GenerateAggregateException()
{
try
{
throw new AggregateException(SendHttp(), new ArgumentException("Invalid parameter", ValidateLength()));
}
catch (Exception e)
{
return e;
}
}
private static Exception SendHttp()
{
try
{
throw new IOException("Network down");
}
catch (Exception e)
{
return e;
}
}
private static Exception ValidateLength()
{
try
{
throw new ArgumentOutOfRangeException(null, "It's over 9000!");
}
catch (Exception e)
{
return e;
}
}
private void CrashWithNullReference_Click(object sender, RoutedEventArgs e)
{
HandleOrThrow(() =>
{
string[] values = { "a", null, "c" };
var b = values[1].Trim();
System.Diagnostics.Debug.WriteLine(b);
});
ErrorPropertiesSource.Clear();
}
private async void CrashInsideAsyncTask_Click(object sender, RoutedEventArgs e)
{
try
{
await FakeService.DoStuffInBackground();
}
catch (Exception ex) when (HandleExceptions.IsChecked.Value)
{
TrackException(ex);
}
ErrorPropertiesSource.Clear();
}
private void ClassLibraryException_Click(object sender, RoutedEventArgs e)
{
CrashUtils.BackgroundExceptionTask().RunSynchronously();
}
private static class FakeService
{
public static async Task DoStuffInBackground()
{
await Task.Run(() => throw new IOException("Server did not respond"));
}
}
private void TrackException(Exception e)
{
var properties = ErrorPropertiesSource.Where(property => property.Key != null && property.Value != null).ToDictionary(property => property.Key, property => property.Value);
if (properties.Count == 0)
{
properties = null;
}
Crashes.TrackError(e, properties, App.GetErrorAttachments().ToArray());
ErrorPropertiesSource.Clear();
}
void HandleOrThrow(Action action)
{
try
{
action();
}
catch (Exception e) when (HandleExceptions.IsChecked.Value)
{
TrackException(e);
}
ErrorPropertiesSource.Clear();
}
private void TextAttachmentTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
textAttachments = TextAttachmentTextBox.Text;
localSettings.Values[Constants.KeyTextErrorAttachments] = textAttachments;
}
private async void FileErrorAttachment_Click(object sender, RoutedEventArgs e)
{
// Open a text file.
FileOpenPicker open = new FileOpenPicker();
open.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
open.FileTypeFilter.Add("*");
// When running on win32, FileOpenPicker needs to know the top-level hwnd via IInitializeWithWindow::Initialize.
if (Window.Current == null)
{
IInitializeWithWindow initializeWithWindowWrapper = open.As<IInitializeWithWindow>();
IntPtr hwnd = GetActiveWindow();
initializeWithWindowWrapper.Initialize(hwnd);
}
StorageFile file = await open.PickSingleFileAsync();
var filePath = string.Empty;
if (file != null)
{
filePath = file.Path;
FileAttachmentLabel.Text = filePath;
}
else
{
FileAttachmentLabel.Text = "The file isn't selected";
}
localSettings.Values[Constants.KeyFileErrorAttachments] = filePath;
}
private void CrashesAddNewProperty_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(ErrorKeyItem.Text) || string.IsNullOrEmpty(ErrorValueItem.Text))
{
return;
}
var property = new Property();
property.Key = ErrorKeyItem.Text;
property.Value = ErrorValueItem.Text;
ErrorKeyItem.Text = "";
ErrorValueItem.Text = "";
ErrorPropertiesSource.Add(property);
}
#endregion
[ComImport, Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInitializeWithWindow
{
void Initialize([In] IntPtr hwnd);
}
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto, PreserveSig = true, SetLastError = false)]
public static extern IntPtr GetActiveWindow();
}
}

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>arm64</Platform>
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>True</PublishReadyToRun>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>x64</Platform>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>True</PublishReadyToRun>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>x86</Platform>
<RuntimeIdentifier>win10-x86</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>True</PublishReadyToRun>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Contoso.WinUI.Desktop.Puppet
{
class Property : INotifyPropertyChanged
{
private string _key;
private string _value;
public string Key
{
get
{
return _key;
}
set
{
if (_key != value)
{
_key = value;
NotifyPropertyChanged();
}
}
}
public string Value
{
get
{
return _value;
}
set
{
if (_value != value)
{
_value = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="Contoso.WinUI.Desktop.Puppet.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</windowsSettings>
</application>
</assembly>

Просмотреть файл

@ -1,5 +1,17 @@
# App Center SDK for .NET Change Log
## Version 4.3.1 (Under development)
### App Center
#### Windows
* **[Feature]** Add support for platform `WinUI in Desktop`. The target version of `WinUI` apps should be `net5.0-windows10.0.17763.0` or higher.
* **[Fix]** Update `Newtonsoft.Json` dependency to version `13.0.1`.
___
## Version 4.3.0
### AppCenter

Просмотреть файл

@ -22,7 +22,7 @@
<Import Project="..\Microsoft.AppCenter.Windows.Shared\Microsoft.AppCenter.Windows.Shared.projitems" Label="Shared" />
<Import Project="..\Microsoft.AppCenter.Shared\Microsoft.AppCenter.Shared.projitems" Label="Shared" />
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.0.2" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'uap10.0.16299'">

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0;net461;net5.0-windows10.0.17763.0</TargetFrameworks>
<RootNamespace>Microsoft.AppCenter</RootNamespace>
<UseWindowsForms>true</UseWindowsForms>
<Version>4.3.1-SNAPSHOT</Version>
@ -16,12 +16,17 @@
<Import Project="..\Microsoft.AppCenter.Windows.Shared\Microsoft.AppCenter.Windows.Shared.projitems" Label="Shared" />
<Import Project="..\Microsoft.AppCenter.Shared\Microsoft.AppCenter.Shared.projitems" Label="Shared" />
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.0.2" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<PackageReference Include="System.Management" Version="4.6.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.6.0" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.18362.2005" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0-windows10.0.17763.0'">
<PackageReference Include="System.Management" Version="5.0.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
<Reference Include="Microsoft.CSharp" />

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#if !NET5_0
using System;
using System.Diagnostics;
using System.Drawing;
@ -196,3 +197,4 @@ namespace Microsoft.AppCenter.Utils
public event EventHandler<UnhandledExceptionOccurredEventArgs> UnhandledExceptionOccurred;
}
}
#endif

Просмотреть файл

@ -0,0 +1,150 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#if NET5_0
using System;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.Foundation.Metadata;
using Windows.UI.Core;
namespace Microsoft.AppCenter.Utils
{
public class ApplicationLifecycleHelper : IApplicationLifecycleHelper
{
public event EventHandler ApplicationSuspended;
public event EventHandler ApplicationResuming;
public event EventHandler<UnhandledExceptionOccurredEventArgs> UnhandledExceptionOccurred;
// True if InvokeResuming has been called at least once during the current process
private static bool _started;
// Considered to be suspended until can verify that has started
private static bool _suspended = true;
// Singleton instance of ApplicationLifecycleHelper
private static ApplicationLifecycleHelper _instance;
public static ApplicationLifecycleHelper Instance
{
get { return _instance ?? (_instance = new ApplicationLifecycleHelper()); }
// Setter for testing
internal set { _instance = value; }
}
/// <summary>
/// Indicates whether the application is currently in a suspended state.
/// </summary>
public bool IsSuspended => _suspended;
public ApplicationLifecycleHelper()
{
// Subscribe to Resuming and Suspending events.
CoreApplication.Suspending += InvokeSuspended;
// If the "LeavingBackground" event is present, use that for Resuming. Else, use CoreApplication.Resuming.
if (ApiInformation.IsEventPresent(typeof(CoreApplication).FullName, "LeavingBackground"))
{
CoreApplication.LeavingBackground += InvokeResuming;
// If the application has anything visible, then it has already started,
// so invoke the resuming event immediately.
HasStartedAndNeedsResume().ContinueWith(completedTask =>
{
if (completedTask.Result)
{
InvokeResuming(null, EventArgs.Empty);
}
});
}
else
{
// In versions of Windows 10 where the LeavingBackground event is unavailable, we consider this point to be
// the start so invoke resuming (and subscribe to future resume events). If InvokeResuming were not called here,
// the resuming event wouldn't be invoked until the *next* time the application is resumed, which is a problem
// if the application is not currently suspended. The side effect is that regardless of whether UI is available
// ever in the process, InvokeResuming will be called at least once (in the case where LeavingBackground isn't
// available).
CoreApplication.Resuming += InvokeResuming;
InvokeResuming(null, EventArgs.Empty);
}
// Subscribe to unhandled errors events.
CoreApplication.UnhandledErrorDetected += (sender, eventArgs) =>
{
try
{
// Intentionally propagate exception to get the exception object that crashed the app.
eventArgs.UnhandledError.Propagate();
}
catch (Exception exception)
{
InvokeUnhandledExceptionOccurred(sender, exception);
// Since UnhandledError.Propagate marks the error as Handled, rethrow in order to only Log and not Handle.
// Use ExceptionDispatchInfo to avoid changing the stack-trace.
ExceptionDispatchInfo.Capture(exception).Throw();
}
};
}
// Determines whether the application has started already and is not suspended,
// but ApplicationLifecycleHelper has not yet fired an initial "resume" event.
private static async Task<bool> HasStartedAndNeedsResume()
{
var needsResume = false;
try
{
// Don't use CurrentSynchronizationContext as that seems to cause an error in Unity applications.
var asyncAction = CoreApplication.MainView?.CoreWindow?.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal, () =>
{
// If started already, a resume has already occurred.
if (_started)
{
return;
}
if (CoreApplication.Views.Any(view => view.CoreWindow != null &&
view.CoreWindow.Visible))
{
needsResume = true;
}
});
if (asyncAction != null)
{
await asyncAction;
}
}
catch (Exception e) when (e is COMException || e is InvalidOperationException)
{
// If MainView can't be accessed, a COMException or InvalidOperationException is thrown. It means that the
// MainView hasn't been created, and thus the UI hasn't appeared yet.
AppCenterLog.Debug(AppCenterLog.LogTag,
"Not invoking resume immediately because UI is not ready.");
}
return needsResume;
}
internal void InvokeUnhandledExceptionOccurred(object sender, Exception exception)
{
UnhandledExceptionOccurred?.Invoke(sender, new UnhandledExceptionOccurredEventArgs(exception));
}
private void InvokeResuming(object sender, object e)
{
_started = true;
_suspended = false;
ApplicationResuming?.Invoke(sender, EventArgs.Empty);
}
private void InvokeSuspended(object sender, object e)
{
_suspended = true;
ApplicationSuspended?.Invoke(sender, EventArgs.Empty);
}
}
}
#endif

Просмотреть файл

@ -4,10 +4,14 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Management;
using System.Reflection;
using System.Runtime.InteropServices;
#if NET5_0
using Windows.ApplicationModel;
#else
using System.Windows.Forms;
#endif
#if NET461
using System.Deployment.Application;
@ -40,7 +44,9 @@ namespace Microsoft.AppCenter.Utils
protected override string GetSdkName()
{
var sdkName = WpfHelper.IsRunningOnWpf ? "appcenter.wpf" : "appcenter.winforms";
#if NETCOREAPP3_0
#if NET5_0
sdkName = $"{sdkName}.net";
#elif NETCOREAPP3_0
sdkName = $"{sdkName}.netcore";
#endif
return sdkName;
@ -145,12 +151,22 @@ namespace Microsoft.AppCenter.Utils
* If the AssemblyInformationalVersion is not applied to an assembly,
* the version number specified by the AssemblyFileVersion attribute is used instead.
*/
#if NET5_0
var packageVersion = Package.Current.Id.Version;
return $"{packageVersion.Major}.{packageVersion.Minor}.{packageVersion.Build}.{packageVersion.Revision}";
#else
return DeploymentVersion ?? Application.ProductVersion;
#endif
}
protected override string GetAppBuild()
{
#if NET5_0
var packageVersion = Package.Current.Id.Version;
return $"{packageVersion.Major}.{packageVersion.Minor}.{packageVersion.Build}.{packageVersion.Revision}";
#else
return DeploymentVersion ?? FileVersion;
#endif
}
protected override string GetScreenSize()
@ -181,6 +197,7 @@ namespace Microsoft.AppCenter.Utils
}
}
#if !NET5_0
private static string FileVersion
{
get
@ -204,6 +221,7 @@ namespace Microsoft.AppCenter.Utils
return Application.ProductVersion;
}
}
#endif
/// <summary>
/// Import GetDeviceCaps function to retreive scale-independent screen size.

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0;net461;net5.0-windows10.0.17763.0</TargetFrameworks>
<RootNamespace>Microsoft.AppCenter.Analytics</RootNamespace>
<Version>4.3.1-SNAPSHOT</Version>
<AssemblyVersion>0.0.0.0</AssemblyVersion>

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0;net461;net5.0-windows10.0.17763.0</TargetFrameworks>
<RootNamespace>Microsoft.AppCenter.Crashes</RootNamespace>
<Version>4.3.1-SNAPSHOT</Version>
<AssemblyVersion>0.0.0.0</AssemblyVersion>

Просмотреть файл

@ -43,7 +43,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="SQLitePCLRaw.bundle_green">
<Version>2.0.2</Version>

Просмотреть файл

@ -84,7 +84,7 @@
<Version>4.13.1</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="MSTest.TestFramework">
<Version>2.1.0</Version>

Просмотреть файл

@ -93,7 +93,7 @@
<Version>4.13.1</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="MSTest.TestFramework">
<Version>2.1.0</Version>

Просмотреть файл

@ -60,7 +60,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="SQLitePCLRaw.bundle_green">
<Version>2.0.2</Version>

Просмотреть файл

@ -118,7 +118,7 @@
<Version>4.13.1</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="MSTest.TestFramework">
<Version>2.1.0</Version>

Просмотреть файл

@ -17,18 +17,26 @@
<dependencies>
<group targetFramework="uap10.0">
<dependency id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.2.8"/>
<dependency id="Newtonsoft.Json" version="12.0.2"/>
<dependency id="Newtonsoft.Json" version="13.0.1"/>
<dependency id="SQLitePCLRaw.bundle_green" version="2.0.2" />
</group>
<group targetFramework="net461">
<dependency id="Newtonsoft.Json" version="12.0.2"/>
<dependency id="Newtonsoft.Json" version="13.0.1"/>
<dependency id="SQLitePCLRaw.bundle_green" version="2.0.2" />
<dependency id="Microsoft.Windows.SDK.Contracts" version="10.0.18362.2005" />
</group>
<group targetFramework="netcoreapp3.0">
<dependency id="Newtonsoft.Json" version="12.0.2"/>
<dependency id="Newtonsoft.Json" version="13.0.1"/>
<dependency id="SQLitePCLRaw.bundle_green" version="2.0.2" />
<dependency id="System.Management" version="4.6.0"/>
<dependency id="System.Configuration.ConfigurationManager" version="4.6.0"/>
<dependency id="Microsoft.Windows.SDK.Contracts" version="10.0.18362.2005"/>
</group>
<group targetFramework="net5.0-windows10.0.17763.0">
<dependency id="Newtonsoft.Json" version="13.0.1"/>
<dependency id="SQLitePCLRaw.bundle_green" version="2.0.2" />
<dependency id="System.Management" version="5.0.0"/>
<dependency id="System.Configuration.ConfigurationManager" version="5.0.0"/>
</group>
<!-- Use empty dependency groups for iOS and Android so that additional dependencies aren't added to them -->
<group targetFramework="MonoAndroid50">
@ -44,7 +52,6 @@
</frameworkAssemblies>
<version>$version$</version>
</metadata>
<files>
<!-- .NET Standard -->
@ -72,5 +79,9 @@
<!-- WindowsDesktop (WPF and WinForms) for .NET Core -->
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.dll" target="lib/netcoreapp3.0" />
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.xml" target="lib/netcoreapp3.0" />
<!-- WinUI-->
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.dll" target="lib/net5.0-windows10.0.17763.0" />
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.xml" target="lib/net5.0-windows10.0.17763.0" />
</files>
</package>

Просмотреть файл

@ -46,5 +46,9 @@
<!-- WindowsDesktop (WPF and WinForms) for .NET Core -->
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.Analytics.dll" target="lib/netcoreapp3.0" />
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.Analytics.xml" target="lib/netcoreapp3.0" />
<!-- WinUI -->
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.Analytics.dll" target="lib/net5.0-windows10.0.17763.0" />
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.Analytics.xml" target="lib/net5.0-windows10.0.17763.0" />
</files>
</package>

Просмотреть файл

@ -52,5 +52,9 @@
<!-- WindowsDesktop (WPF and WinForms) for .NET Core -->
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.Crashes.dll" target="lib/netcoreapp3.0" />
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.Crashes.xml" target="lib/netcoreapp3.0" />
<!-- WinUI -->
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.Crashes.dll" target="lib/net5.0-windows10.0.17763.0" />
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.Crashes.xml" target="lib/net5.0-windows10.0.17763.0" />
</files>
</package>

Просмотреть файл

@ -17,18 +17,26 @@
<dependencies>
<group targetFramework="uap10.0">
<dependency id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.2.8"/>
<dependency id="Newtonsoft.Json" version="12.0.2"/>
<dependency id="Newtonsoft.Json" version="13.0.1"/>
<dependency id="SQLitePCLRaw.bundle_green" version="2.0.2" />
</group>
<group targetFramework="net461">
<dependency id="Newtonsoft.Json" version="12.0.2"/>
<dependency id="Newtonsoft.Json" version="13.0.1"/>
<dependency id="SQLitePCLRaw.bundle_green" version="2.0.2" />
<dependency id="Microsoft.Windows.SDK.Contracts" version="10.0.18362.2005" />
</group>
<group targetFramework="netcoreapp3.0">
<dependency id="Newtonsoft.Json" version="12.0.2"/>
<dependency id="Newtonsoft.Json" version="13.0.1"/>
<dependency id="SQLitePCLRaw.bundle_green" version="2.0.2" />
<dependency id="System.Management" version="4.6.0"/>
<dependency id="System.Configuration.ConfigurationManager" version="4.6.0"/>
<dependency id="Microsoft.Windows.SDK.Contracts" version="10.0.18362.2005"/>
</group>
<group targetFramework="net5.0-windows10.0.17763.0">
<dependency id="Newtonsoft.Json" version="13.0.1"/>
<dependency id="SQLitePCLRaw.bundle_green" version="2.0.2" />
<dependency id="System.Management" version="5.0.0"/>
<dependency id="System.Configuration.ConfigurationManager" version="5.0.0"/>
</group>
</dependencies>
<frameworkAssemblies>
@ -51,5 +59,9 @@
<!-- WindowsDesktop (WPF and WinForms) for .NET Core -->
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.dll" target="lib/netcoreapp3.0" />
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.xml" target="lib/netcoreapp3.0" />
<!-- WinUI -->
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.dll" target="lib/net5.0-windows10.0.17763.0" />
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.xml" target="lib/net5.0-windows10.0.17763.0" />
</files>
</package>

Просмотреть файл

@ -31,5 +31,9 @@
<!-- WindowsDesktop (WPF and WinForms) for .NET Core -->
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.Analytics.dll" target="lib/netcoreapp3.0" />
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.Analytics.xml" target="lib/netcoreapp3.0" />
<!-- WinUI -->
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.Analytics.dll" target="lib/net5.0-windows10.0.17763.0" />
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.Analytics.xml" target="lib/net5.0-windows10.0.17763.0" />
</files>
</package>

Просмотреть файл

@ -37,5 +37,9 @@
<!-- WindowsDesktop (WPF and WinForms) for .NET Core -->
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.Crashes.dll" target="lib/netcoreapp3.0" />
<file src="$windows_desktop_netcore_dir$/Microsoft.AppCenter.Crashes.xml" target="lib/netcoreapp3.0" />
<!-- WinUI -->
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.Crashes.dll" target="lib/net5.0-windows10.0.17763.0" />
<file src="$windows_desktop_net_5_dir$/Microsoft.AppCenter.Crashes.xml" target="lib/net5.0-windows10.0.17763.0" />
</files>
</package>

Просмотреть файл

@ -45,6 +45,11 @@
<assembly path="SDK/AppCenterAnalytics/Microsoft.AppCenter.Analytics.WindowsDesktop/bin/Release/netcoreapp3.0/Microsoft.AppCenter.Analytics.dll"/>
<assembly path="SDK/AppCenterCrashes/Microsoft.AppCenter.Crashes.WindowsDesktop/bin/Release/netcoreapp3.0/Microsoft.AppCenter.Crashes.dll"/>
</group>
<group id="windows_desktop_net_5" folder="WindowsDesktopNet5Assemblies" buildGroup="windows">
<assembly path="SDK/AppCenter/Microsoft.AppCenter.WindowsDesktop/bin/Release/net5.0-windows10.0.17763.0/Microsoft.AppCenter.dll"/>
<assembly path="SDK/AppCenterAnalytics/Microsoft.AppCenter.Analytics.WindowsDesktop/bin/Release/net5.0-windows10.0.17763.0/Microsoft.AppCenter.Analytics.dll"/>
<assembly path="SDK/AppCenterCrashes/Microsoft.AppCenter.Crashes.WindowsDesktop/bin/Release/net5.0-windows10.0.17763.0/Microsoft.AppCenter.Crashes.dll"/>
</group>
<group id="uwp" folder="UWPAssemblies" buildGroup="windows">
<assembly path="SDK/AppCenter/Microsoft.AppCenter.UWP/bin/Release/uap10.0.16299/Microsoft.AppCenter.dll"/>
<assembly path="SDK/AppCenterAnalytics/Microsoft.AppCenter.Analytics.UWP/bin/Release/uap10.0.16299/Microsoft.AppCenter.Analytics.dll"/>