[C#/UWP] AppDiagnosticInfo 클래스 : RequestInfoAsync 정적 메소드를 사용해 앱 진단 정보 리스트 구하기
C#/UWP 2021. 6. 5. 21:03728x90
반응형
728x170
▶ Package.appxmanifest
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="mp uap iot rescap">
<Identity
Name="1e3306d1-7340-4412-a1b7-e908babd8ddb"
Publisher="CN=king"
Version="1.0.0.0" />
<mp:PhoneIdentity
PhoneProductId="1e3306d1-7340-4412-a1b7-e908babd8ddb"
PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>TestProject</DisplayName>
<PublisherDisplayName>king</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal"
MinVersion="10.0.0.0"
MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="TestProject.App">
<uap:VisualElements
DisplayName="AppDiagnosticInfo 클래스 : RequestInfoAsync 정적 메소드를 사용해 앱 진단 정보 리스트 구하기"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png"
Description="TestProject"
BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="appDiagnostics" />
</Capabilities>
</Package>
728x90
▶ DeviceFormFactorType.cs
namespace TestProject
{
/// <summary>
/// 장치 폼 팩터 타입
/// </summary>
public enum DeviceFormFactorType
{
/// <summary>
/// 알 수 없음
/// </summary>
Unknown,
/// <summary>
/// 모바일
/// </summary>
Mobile,
/// <summary>
/// 데스크톱
/// </summary>
Desktop,
/// <summary>
/// 타블렛
/// </summary>
Tablet,
/// <summary>
/// IoT
/// </summary>
IoT,
/// <summary>
/// 서피스 허브
/// </summary>
SurfaceHub,
/// <summary>
/// 엑스박스
/// </summary>
Xbox,
/// <summary>
/// 기타
/// </summary>
Other
}
}
300x250
▶ EnergyQuotaStateEx.cs
namespace TestProject
{
/// <summary>
/// 에너지 할당 상태 (확장)
/// </summary>
public enum EnergyQuotaStateEx
{
/// <summary>
/// Unknown
/// </summary>
Unknown,
/// <summary>
/// Over
/// </summary>
Over,
/// <summary>
/// Under
/// </summary>
Under,
/// <summary>
/// Multiple
/// </summary>
Multiple,
/// <summary>
/// NotApplicable
/// </summary>
NotApplicable
}
}
▶ ExecutionStateEx.cs
namespace TestProject
{
/// <summary>
/// 실행 상태 (확장)
/// </summary>
public enum ExecutionStateEx
{
/// <summary>
/// Unknown
/// </summary>
Unknown,
/// <summary>
/// Running
/// </summary>
Running,
/// <summary>
/// Suspending
/// </summary>
Suspending,
/// <summary>
/// Suspended
/// </summary>
Suspended,
/// <summary>
/// NotRunning
/// </summary>
NotRunning,
/// <summary>
/// Multiple
/// </summary>
Multiple,
/// <summary>
/// NotApplicable
/// </summary>
NotApplicable
}
}
▶ AppAggregateModel.cs
namespace TestProject
{
/// <summary>
/// 앱 집계 모델
/// </summary>
public class AppAggregateModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 커밋 제한 - CommitLimit
/// <summary>
/// 커밋 제한
/// </summary>
public ulong CommitLimit { get; internal set; }
#endregion
#region 전체 커밋 - TotalCommit
/// <summary>
/// 전체 커밋
/// </summary>
public ulong TotalCommit { get; internal set; }
#endregion
#region 개인 커밋 - PrivateCommit
/// <summary>
/// 개인 커밋
/// </summary>
public ulong PrivateCommit { get; internal set; }
#endregion
#region 백그라운드 태스크 카운트 - BackgroundTaskCount
/// <summary>
/// 백그라운드 태스크 카운트
/// </summary>
public int BackgroundTaskCount { get; internal set; }
#endregion
#region 실행 상태 - ExecutionState
/// <summary>
/// 실행 상태
/// </summary>
public ExecutionStateEx ExecutionState { get; internal set; }
#endregion
#region 에너지 할당 상태 - EnergyQuotaState
/// <summary>
/// 에너지 할당 상태
/// </summary>
public EnergyQuotaStateEx EnergyQuotaState { get; internal set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - AppAggregateModel(commitLimit, totalCommit, privateCommit, backgroundTaskCount, executionState, energyQuotaState)
/// <summary>
/// 생성자
/// </summary>
/// <param name="commitLimit">커밋 제한</param>
/// <param name="totalCommit">전체 커밋</param>
/// <param name="privateCommit">개인 커밋</param>
/// <param name="backgroundTaskCount">백그라운드 태스크 카운트</param>
/// <param name="executionState">실행 상태</param>
/// <param name="energyQuotaState">에너지 할당 상태</param>
public AppAggregateModel
(
ulong commitLimit,
ulong totalCommit,
ulong privateCommit,
int backgroundTaskCount,
ExecutionStateEx executionState,
EnergyQuotaStateEx energyQuotaState
)
{
CommitLimit = commitLimit;
TotalCommit = totalCommit;
PrivateCommit = privateCommit;
BackgroundTaskCount = backgroundTaskCount;
ExecutionState = executionState;
EnergyQuotaState = energyQuotaState;
}
#endregion
}
}
▶ AppModel.cs
using System.ComponentModel;
using Windows.System;
using Windows.UI.Xaml.Media.Imaging;
namespace TestProject
{
/// <summary>
/// 앱 모델
/// </summary>
public class AppModel : INotifyPropertyChanged
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Event
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 속성 변경시 이벤트 - PropertyChanged
/// <summary>
/// 속성 변경시 이벤트
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 커밋 제한
/// </summary>
private ulong commitLimit;
/// <summary>
/// 전체 커밋
/// </summary>
private ulong totalCommit;
/// <summary>
/// 개인 커밋
/// </summary>
private ulong privateCommit;
/// <summary>
/// 실행 상태
/// </summary>
private ExecutionStateEx executionState;
/// <summary>
/// 에너지 할당 상태
/// </summary>
private EnergyQuotaStateEx energyQuotaState;
/// <summary>
/// 백그라운드 태스크 카운트
/// </summary>
private int backgroundTaskCount;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 앱 진단 정보 - ADI
/// <summary>
/// 앱 진단 정보
/// </summary>
public AppDiagnosticInfo ADI { get; internal set; }
#endregion
#region ID - ID
/// <summary>
/// ID
/// </summary>
public string ID { get; internal set; }
#endregion
#region 부모 ID - ParentID
/// <summary>
/// 부모 ID
/// </summary>
public string ParentID { get; internal set; }
#endregion
#region 로고 - Logo
/// <summary>
/// 로고
/// </summary>
public BitmapImage Logo { get; internal set; }
#endregion
#region 명칭 - Name
/// <summary>
/// 명칭
/// </summary>
public string Name { get; internal set; }
#endregion
#region 프로세스 ID - ProcessID
/// <summary>
/// 프로세스 ID
/// </summary>
public int ProcessID { get; internal set; }
#endregion
#region 커미 제한 - CommitLimit
/// <summary>
/// 커미 제한
/// </summary>
public ulong CommitLimit
{
get
{
return this.commitLimit;
}
set
{
if(this.commitLimit != value)
{
this.commitLimit = value;
FirePropertyChangedEvent("CommitLimit");
}
}
}
#endregion
#region 전체 커밋 - TotalCommit
/// <summary>
/// 전체 커밋
/// </summary>
public ulong TotalCommit
{
get
{
return this.totalCommit;
}
set
{
if(this.totalCommit != value)
{
this.totalCommit = value;
FirePropertyChangedEvent("TotalCommit");
}
}
}
#endregion
#region 개인 커밋 - PrivateCommit
/// <summary>
/// 개인 커밋
/// </summary>
public ulong PrivateCommit
{
get
{
return this.privateCommit;
}
set
{
if(this.privateCommit != value)
{
this.privateCommit = value;
FirePropertyChangedEvent("PrivateCommit");
}
}
}
#endregion
#region 실행 상태 - ExecutionState
/// <summary>
/// 실행 상태
/// </summary>
public ExecutionStateEx ExecutionState
{
get
{
return this.executionState;
}
set
{
if(this.executionState != value)
{
this.executionState = value;
FirePropertyChangedEvent("ExecutionState");
}
}
}
#endregion
#region 에너지 할당 상태 - EnergyQuotaState
/// <summary>
/// 에너지 할당 상태
/// </summary>
public EnergyQuotaStateEx EnergyQuotaState
{
get
{
return this.energyQuotaState;
}
set
{
if(this.energyQuotaState != value)
{
this.energyQuotaState = value;
FirePropertyChangedEvent("EnergyQuotaState");
}
}
}
#endregion
#region 백그라운드 태스크 카운트 - BackgroundTaskCount
/// <summary>
/// 백그라운드 태스크 카운트
/// </summary>
public int BackgroundTaskCount
{
get
{
return this.backgroundTaskCount;
}
set
{
if(this.backgroundTaskCount != value)
{
this.backgroundTaskCount = value;
FirePropertyChangedEvent("BackgroundTaskCount");
}
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - AppModel(adi, id, logo, name, commitLimit, totalCommit, privateCommit, executionState, energyQuotaState, backgroundTaskCount)
/// <summary>
/// 생성자
/// </summary>
/// <param name="adi">앱 진단 정보</param>
/// <param name="id">ID</param>
/// <param name="logo">로고</param>
/// <param name="name">명칭</param>
/// <param name="commitLimit">커밋 제한</param>
/// <param name="totalCommit">전체 커밋</param>
/// <param name="privateCommit">개인 커밋</param>
/// <param name="executionState">실행 상태</param>
/// <param name="energyQuotaState">에너지 할당 상태</param>
/// <param name="backgroundTaskCount">백그라운드 태스크 카운트</param>
public AppModel
(
AppDiagnosticInfo adi,
string id,
BitmapImage logo,
string name,
ulong commitLimit,
ulong totalCommit,
ulong privateCommit,
ExecutionStateEx executionState,
EnergyQuotaStateEx energyQuotaState,
int backgroundTaskCount
)
{
ADI = adi;
ID = id;
Logo = logo;
Name = name;
this.commitLimit = commitLimit;
this.totalCommit = totalCommit;
this.privateCommit = privateCommit;
this.executionState = executionState;
this.energyQuotaState = energyQuotaState;
this.backgroundTaskCount = backgroundTaskCount;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 업데이트하기 - Update(commitLimit, totalCommit, privateCommit, executionState, energyQuotaState, backgroundTaskCount)
/// <summary>
/// 업데이트하기
/// </summary>
/// <param name="commitLimit">커밋 제한</param>
/// <param name="totalCommit">전체 커밋</param>
/// <param name="privateCommit">개인 커밋</param>
/// <param name="executionState">실행 상태</param>
/// <param name="energyQuotaState">에너지 할당 상태</param>
/// <param name="backgroundTaskCount">백그라운트 태스크 카운트</param>
public void Update
(
ulong commitLimit,
ulong totalCommit,
ulong privateCommit,
ExecutionStateEx executionState,
EnergyQuotaStateEx energyQuotaState,
int backgroundTaskCount
)
{
CommitLimit = commitLimit;
TotalCommit = totalCommit;
PrivateCommit = privateCommit;
ExecutionState = executionState;
EnergyQuotaState = energyQuotaState;
BackgroundTaskCount = backgroundTaskCount;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propertyName)
/// <summary>
/// 속성 변경시 이벤트 발생시키기
/// </summary>
/// <param name="propertyName">속성명</param>
private void FirePropertyChangedEvent(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
▶ ByteToMegabyteConverter.cs
using System;
using Windows.UI.Xaml.Data;
namespace TestProject
{
/// <summary>
/// 바이트→메가바이트 변환자
/// </summary>
public class ByteToMegabyteConverter : IValueConverter
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 변환하기 - Convert(sourceValue, targetType, parameter, language)
/// <summary>
/// 변환하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="targetType">타겟 타입</param>
/// <param name="parameter">매개 변수</param>
/// <param name="language">언어</param>
/// <returns>변환 값</returns>
public object Convert(object sourceValue, Type targetType, object parameter, string language)
{
if(sourceValue == null)
{
return null;
}
double temporaryValue = (double)((ulong)sourceValue) / (1024 * 1024);
string targetValue = $"{temporaryValue:N2} MB";
return targetValue;
}
#endregion
#region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, language)
/// <summary>
/// 역변환하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="targetType">타겟 타입</param>
/// <param name="parameter">매개 변수</param>
/// <param name="language">언어</param>
/// <returns>역변환 값</returns>
public object ConvertBack(object sourceValue, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
#endregion
}
}
▶ EnergyQuotaStateConverter.cs
using System;
using Windows.UI.Xaml.Data;
namespace TestProject
{
/// <summary>
/// 에너지 할당 상태 변환자
/// </summary>
public class EnergyQuotaStateConverter : IValueConverter
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 변환하기 - Convert(sourceValue, targetType, parameter, language)
/// <summary>
/// 변환하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="targetType">타겟 타입</param>
/// <param name="parameter">매개 변수</param>
/// <param name="language">언어</param>
/// <returns>변환 값</returns>
public object Convert(object sourceValue, Type targetType, object parameter, string language)
{
if(sourceValue == null)
{
return null;
}
string targetValue = string.Empty;
EnergyQuotaStateEx energyState = (EnergyQuotaStateEx)sourceValue;
if(energyState != EnergyQuotaStateEx.NotApplicable)
{
targetValue = energyState.ToString();
}
return targetValue;
}
#endregion
#region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, language)
/// <summary>
/// 역변환하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="targetType">타겟 타입</param>
/// <param name="parameter">매개 변수</param>
/// <param name="language">언어</param>
/// <returns>역변환 값</returns>
public object ConvertBack(object sourceValue, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
#endregion
}
}
▶ MemoryLimitConverter.cs
using System;
using Windows.UI.Xaml.Data;
namespace TestProject
{
/// <summary>
/// 메모리 제한 변환자
/// </summary>
public class MemoryLimitConverter : IValueConverter
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 메가 바이트
/// </summary>
private const ulong MB = 1024 * 1024;
/// <summary>
/// 1기가 바이트
/// </summary>
private const ulong ONE_GB = MB * 1024;
/// <summary>
/// 부호없는 배정도 정수 - 1기가 바이트
/// </summary>
private const ulong ULONG_MAX_MINUS_ONE_GB = ulong.MaxValue - ONE_GB;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 변환하기 - Convert(sourceValue, targetType, parameter, language)
/// <summary>
/// 변환하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="targetType">타겟 타입</param>
/// <param name="parameter">매개 변수</param>
/// <param name="language">언어</param>
/// <returns>변환 값</returns>
public object Convert(object sourceValue, Type targetType, object parameter, string language)
{
if(sourceValue == null)
{
return null;
}
string targetValue = string.Empty;
ulong unsignedLongInteger = (ulong)sourceValue;
if
(
App.DeviceFormFactorType == DeviceFormFactorType.Desktop ||
App.DeviceFormFactorType == DeviceFormFactorType.Tablet ||
unsignedLongInteger >= ULONG_MAX_MINUS_ONE_GB
)
{
targetValue = "n/a";
}
else if(unsignedLongInteger >= 0)
{
double temporaryValue = (double)unsignedLongInteger / MB;
targetValue = $"{temporaryValue:N2} MB";
}
return targetValue;
}
#endregion
#region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, language)
/// <summary>
/// 역변환하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="targetType">타겟 타입</param>
/// <param name="parameter">매개 변수</param>
/// <param name="language">언어</param>
/// <returns>역변환 값</returns>
public object ConvertBack(object sourceValue, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
#endregion
}
}
▶ NegativeValueConverter.cs
using System;
using Windows.UI.Xaml.Data;
namespace TestProject
{
/// <summary>
/// 음수 값 변환자
/// </summary>
public class NegativeValueConverter : IValueConverter
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 변환하기 - Convert(sourceValue, targetType, parameter, language)
/// <summary>
/// 변환하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="targetType">타겟 타입</param>
/// <param name="parameter">매개 변수</param>
/// <param name="language">언어</param>
/// <returns>변환 값</returns>
public object Convert(object sourceValue, Type targetType, object parameter, string language)
{
if(sourceValue == null)
{
return null;
}
string targetValue = string.Empty;
int integer = (int)sourceValue;
if(integer >= 0)
{
targetValue = sourceValue.ToString();
}
return targetValue;
}
#endregion
#region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, language)
/// <summary>
/// 역변환하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="targetType">타겟 타입</param>
/// <param name="parameter">매개 변수</param>
/// <param name="language">언어</param>
/// <returns>역변환 값</returns>
public object ConvertBack(object sourceValue, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
#endregion
}
}
▶ MainPage.xaml
<Page x:Class="TestProject.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:local="using:TestProject"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
FontFamily="나눔고딕코딩"
FontSize="16">
<Page.Resources>
<local:ByteToMegabyteConverter x:Key="ByteToMegabyteConverterKey" />
<local:MemoryLimitConverter x:Key="MemoryLimitConverterKey" />
<local:NegativeValueConverter x:Key="NegativeValueConverterKey" />
<local:EnergyQuotaStateConverter x:Key="EnergyQuotaStateConverterKey" />
</Page.Resources>
<Grid>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls:DataGrid Name="dataGrid" Grid.Row="0"
BorderBrush="Black"
BorderThickness="1"
AutoGenerateColumns="False">
<controls:DataGrid.Columns>
<controls:DataGridTextColumn
Header="명칭"
Width="Auto"
Binding="{Binding Name}" />
<controls:DataGridTextColumn
Header="커밋 제한"
Width="Auto"
Binding="{Binding CommitLimit, Converter={StaticResource MemoryLimitConverterKey}}" />
<controls:DataGridTextColumn
Header="전체 커밋"
Width="Auto"
Binding="{Binding TotalCommit, Converter={StaticResource ByteToMegabyteConverterKey}}" />
<controls:DataGridTextColumn
Header="개인 커밋"
Width="Auto"
Binding="{Binding PrivateCommit, Converter={StaticResource ByteToMegabyteConverterKey}}" />
<controls:DataGridTextColumn
Header="실행 상태"
Width="Auto"
Binding="{Binding ExecutionState}" />
<controls:DataGridTextColumn
Header="에너지 할당 상태"
Width="Auto"
Binding="{Binding EnergyQuotaState, Converter={StaticResource EnergyQuotaStateConverterKey}}" />
<controls:DataGridTextColumn
Header="백그라운드 태스크"
Width="Auto"
Binding="{Binding BackgroundTaskCount, Converter={StaticResource NegativeValueConverterKey}}" />
</controls:DataGrid.Columns>
</controls:DataGrid>
<Button Name="refreshButton" Grid.Row="2"
HorizontalAlignment="Right"
Width="100"
Height="30"
Content="갱신" />
</Grid>
</Grid>
</Page>
▶ MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage.Streams;
using Windows.System;
using Windows.System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace TestProject
{
/// <summary>
/// 메인 페이지
/// </summary>
public sealed partial class MainPage : Page
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 잠금 객체
/// </summary>
private static readonly object _lockObject = new object();
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 디폴트 프로세스 이미지
/// </summary>
private BitmapImage defaultProcessImage;
/// <summary>
/// 디폴트 앱 이미지
/// </summary>
private BitmapImage defaultAppImage;
/// <summary>
/// 앱 컬렉션
/// </summary>
private ObservableCollection<AppModel> appCollection = new ObservableCollection<AppModel>();
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainPage()
/// <summary>
/// 생성자
/// </summary>
public MainPage()
{
InitializeComponent();
this.defaultProcessImage = new BitmapImage(new Uri("ms-appx:/Assets/default-process-icon.png", UriKind.Absolute));
this.defaultAppImage = new BitmapImage(new Uri("ms-appx:/Assets/default-app-icon.png" , UriKind.Absolute));
this.dataGrid.ItemsSource = this.appCollection;
this.refreshButton.Click += refreshButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 탐색되는 경우 처리하기 - OnNavigatedTo(e)
/// <summary>
/// 탐색되는 경우 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
await AppDiagnosticInfo.RequestAccessAsync();
UpdateAppData();
base.OnNavigatedTo(e);
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 갱신 버튼 클릭시 처리하기 - refreshButton_Click(sender, e)
/// <summary>
/// 갱신 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void refreshButton_Click(object sender, RoutedEventArgs e)
{
UpdateAppData();
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 죽은 행 제거하기 - RemoveDeadRows(adiList)
/// <summary>
/// 죽은 행 제거하기
/// </summary>
/// <param name="adiList">앱 진단 정보 리스트</param>
private void RemoveDeadRows(IList<AppDiagnosticInfo> adiList)
{
for(int i = 0; i < this.appCollection.Count; i++)
{
bool isFound = false;
AppModel app = this.appCollection[i];
foreach(AppDiagnosticInfo adi in adiList)
{
if(adi.AppInfo.AppUserModelId == app.ID)
{
isFound = true;
}
}
if(!isFound)
{
this.appCollection.Remove(app);
}
}
}
#endregion
#region 개인 커밋 구하기 - GetPrivateCommit(pdi)
/// <summary>
/// 개인 커밋 구하기
/// </summary>
/// <param name="pdi">프로세스 진단 정보</param>
/// <returns>개인 커밋</returns>
private ulong GetPrivateCommit(ProcessDiagnosticInfo pdi)
{
ulong privateCommit = 0;
if(pdi.MemoryUsage != null)
{
ProcessMemoryUsageReport report = pdi.MemoryUsage.GetReport();
if(report != null)
{
privateCommit = report.PageFileSizeInBytes;
}
}
return privateCommit;
}
#endregion
#region 앱 집계 구하기 - GetAppAggregate(appName, argi, totalPrivateCommit)
/// <summary>
/// 앱 집계 구하기
/// </summary>
/// <param name="appName">앱 명칭</param>
/// <param name="argi">앱 리소스 그룹 정보</param>
/// <param name="totalPrivateCommit">전체 개인 커밋</param>
/// <returns>앱 집계</returns>
private AppAggregateModel GetAppAggregate(string appName, AppResourceGroupInfo argi, ulong totalPrivateCommit)
{
ulong commitLimit = 0;
ulong totalCommit = 0;
ulong privateCommit = 0;
int backgroundTaskCount = 0;
ExecutionStateEx executionState = ExecutionStateEx.Unknown;
EnergyQuotaStateEx energyQuotaState = EnergyQuotaStateEx.Unknown;
try
{
AppResourceGroupMemoryReport argmReport = argi.GetMemoryReport();
if(argmReport != null)
{
commitLimit = argmReport.CommitUsageLimit;
totalCommit = argmReport.TotalCommitUsage;
privateCommit = argmReport.PrivateCommitUsage;
}
}
catch
{
}
try
{
AppResourceGroupStateReport argsReport = argi.GetStateReport();
if(argsReport != null)
{
executionState = (ExecutionStateEx)argsReport.ExecutionState;
energyQuotaState = (EnergyQuotaStateEx)argsReport.EnergyQuotaState;
}
}
catch
{
}
try
{
IList<AppResourceGroupBackgroundTaskReport> argbtReportList = argi.GetBackgroundTaskReports();
if(argbtReportList != null)
{
backgroundTaskCount = argbtReportList.Count;
}
}
catch
{
}
AppAggregateModel appAggregate = new AppAggregateModel
(
commitLimit,
totalCommit,
privateCommit,
backgroundTaskCount,
executionState,
energyQuotaState
);
return appAggregate;
}
#endregion
#region 로고 구하기 - GetLogo(adi)
/// <summary>
/// 로고 구하기
/// </summary>
/// <param name="adi">앱 진단 정보</param>
/// <returns>로고 비트맵 이미지</returns>
private BitmapImage GetLogo(AppDiagnosticInfo adi)
{
BitmapImage bitmapImage = new BitmapImage();
if(adi != null && adi.AppInfo != null && adi.AppInfo.DisplayInfo != null)
{
RandomAccessStreamReference streamReference = adi.AppInfo.DisplayInfo.GetLogo(new Size(64, 64));
IAsyncOperation<IRandomAccessStreamWithContentType> asyncOperation = streamReference.OpenReadAsync();
Task<IRandomAccessStreamWithContentType> task = asyncOperation.AsTask();
task.Wait();
IRandomAccessStreamWithContentType contentType = task.Result;
IAsyncAction asyncAction = bitmapImage.SetSourceAsync(contentType);
}
return bitmapImage;
}
#endregion
#region 앱 추가/업데이트하기 - AddOrUpdateApp(adi, appAggregate, executionState)
/// <summary>
/// 앱 추가/업데이트하기
/// </summary>
/// <param name="adi">앱 진단 정보</param>
/// <param name="appAggregate">앱 집계</param>
/// <param name="executionState">실행 상태</param>
/// <returns>처리 결과</returns>
private bool AddOrUpdateApp(AppDiagnosticInfo adi, AppAggregateModel appAggregate, ExecutionStateEx executionState)
{
bool result = false;
string name = "(unknown)";
string appID = string.Empty;
if(adi.AppInfo != null && adi.AppInfo.DisplayInfo != null)
{
appID = adi.AppInfo.AppUserModelId;
name = adi.AppInfo.DisplayInfo.DisplayName;
}
bool isAppFound = false;
foreach(AppModel app in this.appCollection)
{
if(appID == app.ID)
{
isAppFound = true;
break;
}
}
if(!isAppFound && executionState != ExecutionStateEx.NotRunning)
{
BitmapImage logo = GetLogo(adi);
AppModel app = new AppModel
(
adi,
appID,
logo,
name,
appAggregate.CommitLimit,
appAggregate.TotalCommit,
appAggregate.PrivateCommit,
appAggregate.ExecutionState,
appAggregate.EnergyQuotaState,
appAggregate.BackgroundTaskCount
);
this.appCollection.Add(app);
result = true;
}
else
{
IEnumerable<AppModel> appEnumerable = this.appCollection.Where(r => r.ID == appID);
if(appEnumerable != null && appEnumerable.Count() > 0)
{
AppModel existingApp = appEnumerable.First();
existingApp.Update
(
appAggregate.CommitLimit,
appAggregate.TotalCommit,
appAggregate.PrivateCommit,
appAggregate.ExecutionState,
appAggregate.EnergyQuotaState,
appAggregate.BackgroundTaskCount
);
}
}
return result;
}
#endregion
#region 앱 데이터 업데이트하기 - UpdateAppData()
/// <summary>
/// 앱 데이터 업데이트하기
/// </summary>
/// <returns>처리 결과</returns>
private bool UpdateAppData()
{
bool result = false;
lock(_lockObject)
{
IAsyncOperation<IList<AppDiagnosticInfo>> adiListAsyncOperation = AppDiagnosticInfo.RequestInfoAsync();
Task<IList<AppDiagnosticInfo>> adiListTask = adiListAsyncOperation.AsTask();
adiListTask.Wait();
IList<AppDiagnosticInfo> adiList = adiListTask.Result;
if(adiList != null)
{
RemoveDeadRows(adiList);
foreach(AppDiagnosticInfo adi in adiList)
{
ulong commitLimit = 0;
ulong totalCommit = 0;
ulong privateCommit = 0;
int backgroundTaskCount = 0;
ExecutionStateEx executionState = ExecutionStateEx.Unknown;
EnergyQuotaStateEx energyQuotaState = EnergyQuotaStateEx.Unknown;
IList<AppResourceGroupInfo> argiList = adi.GetResourceGroups();
if(argiList != null)
{
foreach(AppResourceGroupInfo argi in argiList)
{
ulong totalPrivateCommit = 0;
IList<ProcessDiagnosticInfo> pdiList = argi.GetProcessDiagnosticInfos();
if(pdiList != null)
{
foreach(ProcessDiagnosticInfo pdi in pdiList)
{
totalPrivateCommit += GetPrivateCommit(pdi);
}
}
AppAggregateModel appAggregate1 = GetAppAggregate(adi.AppInfo.DisplayInfo.DisplayName, argi, totalPrivateCommit);
commitLimit += appAggregate1.CommitLimit;
totalCommit += appAggregate1.TotalCommit;
privateCommit += appAggregate1.PrivateCommit;
backgroundTaskCount += appAggregate1.BackgroundTaskCount;
if(executionState != appAggregate1.ExecutionState)
{
if(executionState == ExecutionStateEx.Unknown)
{
executionState = appAggregate1.ExecutionState;
}
else
{
executionState = ExecutionStateEx.Multiple;
}
}
if(energyQuotaState != appAggregate1.EnergyQuotaState)
{
if(energyQuotaState == EnergyQuotaStateEx.Unknown)
{
energyQuotaState = appAggregate1.EnergyQuotaState;
}
else
{
energyQuotaState = EnergyQuotaStateEx.Multiple;
}
}
}
}
AppAggregateModel appAggregate2 = new AppAggregateModel
(
commitLimit,
totalCommit,
privateCommit,
backgroundTaskCount,
executionState,
energyQuotaState
);
bool isAppAdded = AddOrUpdateApp(adi, appAggregate2, executionState);
if(isAppAdded)
{
result = true;
}
}
}
}
return result;
}
#endregion
}
}
▶ App.xaml
<Application x:Class="TestProject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>
▶ App.xaml.cs
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Graphics.Display;
using Windows.System.Profile;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace TestProject
{
/// <summary>
/// 앱
/// </summary>
sealed partial class App : Application
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 장치 폼 팩터 타입
/// </summary>
private static DeviceFormFactorType _deviceFormFactorType = DeviceFormFactorType.Unknown;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 장치 폼 팩터 타입 - DeviceFormFactorType
/// <summary>
/// 장치 폼 팩터 타입
/// </summary>
public static DeviceFormFactorType DeviceFormFactorType
{
get
{
if(_deviceFormFactorType == DeviceFormFactorType.Unknown)
{
switch(AnalyticsInfo.VersionInfo.DeviceFamily)
{
case "Windows.Mobile" :
_deviceFormFactorType = DeviceFormFactorType.Mobile;
break;
case "Windows.Desktop" :
_deviceFormFactorType = UIViewSettings.GetForCurrentView().UserInteractionMode == UserInteractionMode.Mouse ?
DeviceFormFactorType.Desktop :
DeviceFormFactorType.Tablet;
break;
case "Windows.Universal" :
_deviceFormFactorType = DeviceFormFactorType.IoT;
break;
case "Windows.Team" :
_deviceFormFactorType = DeviceFormFactorType.SurfaceHub;
break;
case "Windows.Xbox" :
_deviceFormFactorType = DeviceFormFactorType.Xbox;
break;
default :
_deviceFormFactorType = DeviceFormFactorType.Other;
break;
}
}
return _deviceFormFactorType;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - App()
/// <summary>
/// 생성자
/// </summary>
public App()
{
InitializeComponent();
Suspending += Application_Suspending;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 시작시 처리하기 - OnLaunched(e)
/// <summary>
/// 시작시 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if(rootFrame == null)
{
rootFrame = new Frame();
rootFrame.NavigationFailed += rootFrame_NavigationFailed;
if(e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
}
Window.Current.Content = rootFrame;
}
if(e.PrelaunchActivated == false)
{
if(rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
Window.Current.Activate();
}
#region 윈도우 크기를 설정한다.
double width = 800d;
double height = 600d;
double dpi = (double)DisplayInformation.GetForCurrentView().LogicalDpi;
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
Size windowSize = new Size(width * 96d / dpi, height * 96d / dpi);
ApplicationView.PreferredLaunchViewSize = windowSize;
Window.Current.Activate();
ApplicationView.GetForCurrentView().TryResizeView(windowSize);
#endregion
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 애플리케이션 정지시 처리하기 - Application_Suspending(sender, e)
/// <summary>
/// 애플리케이션 정지시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Application_Suspending(object sender, SuspendingEventArgs e)
{
SuspendingDeferral deferral = e.SuspendingOperation.GetDeferral();
deferral.Complete();
}
#endregion
#region 루트 프레임 네비게이션 실패시 처리하기 - rootFrame_NavigationFailed(sender, e)
/// <summary>
/// 루트 프레임 네비게이션 실패시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void rootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception($"페이지 로드를 실패했습니다 : {e.SourcePageType.FullName}");
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > UWP' 카테고리의 다른 글
[C#/UWP] Button 엘리먼트 : Style 속성에서 AccentButtonStyle 리소스 사용하기 (0) | 2021.06.20 |
---|---|
[C#/UWP] Button 엘리먼트 : Style 속성에서 ButtonRevealStyle 리소스 사용하기 (0) | 2021.06.20 |
[C#/UWP] TextBlock 엘리먼트 : TextWrapping 속성 사용하기 (0) | 2021.06.20 |
[C#/UWP] Button 엘리먼트 : 이미지 버튼 사용하기 (0) | 2021.06.20 |
[C#/UWP] 누겟 설치 : Microsoft.Toolkit.Uwp.UI.Animations (0) | 2021.06.05 |
[C#/UWP] AppDiagnosticInfo 클래스 : RequestInfoAsync 정적 메소드를 사용해 앱 진단 정보 리스트 구하기 (0) | 2021.06.05 |
[C#/UWP] DataGrid 엘리먼트 사용하기 (0) | 2021.06.05 |
[C#/UWP] 누겟 설치 : Microsoft.Toolkit.Uwp.UI.Controls.DataGrid (0) | 2021.06.05 |
[C#/UWP] ProcessDiagnosticInfo 클래스 : GetForProcesses 정적 메소드를 사용해 프로세스 진단 정보 리스트 구하기 (0) | 2021.06.05 |
[C#/UWP] AppDiagnosticInfo 클래스 : RequestAccessAsync 정적 메소드를 사용해 진단 정보에 대한 액세스 요청하기 (0) | 2021.06.05 |
[C#/UWP] AppBarToggleButton 엘리먼트 사용하기 (0) | 2021.06.05 |
댓글을 달아 주세요