첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
------------------------------------------------------------------------------------------------------------------------------------------------------
728x90
728x170

TestProject.zip
0.12MB

▶ TabHeader.xaml

<UserControl x:Class="TestProject.TabHeader"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    IsTabStop="False">
    <StackPanel>
        <Grid>
            <Image Name="selectedImage"
                Width="48"
                Height="48"
                Stretch="Uniform"
                Source="{Binding SelectedImage}" />
            <Image Name="unselectedImage"
                Width="48"
                Height="48"
                Stretch="Uniform"
                Source="{Binding UnselectedImage}" />
        </Grid>
        <TextBlock
            Style="{StaticResource CaptionTextBlockStyle}"
            HorizontalAlignment="Center"
            Margin="2 5 2 7"
            LineStackingStrategy="BlockLineHeight"
            LineHeight="14"
            MaxLines="1"
            IsTextScaleFactorEnabled="False"
            TextAlignment="Center"
            FontFamily="Segoe UI"
            Text="{Binding Label}" />
    </StackPanel>
</UserControl>

 

728x90

 

▶ TabHeader.xaml.cs

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace TestProject
{
    /// <summary>
    /// 탭 헤더
    /// </summary>
    public sealed partial class TabHeader : UserControl
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 선택 이미지 속성 - SelectedImageProperty

        /// <summary>
        /// 선택 이미지 속성
        /// </summary>
        public static readonly DependencyProperty SelectedImageProperty = DependencyProperty.Register
        (
            "SelectedImage",
            typeof(string),
            typeof(TabHeader),
            null
        );

        #endregion
        #region 미선택 이미지 속성 - UnselectedImageProperty

        /// <summary>
        /// 미선택 이미지 속성
        /// </summary>
        public static readonly DependencyProperty UnselectedImageProperty = DependencyProperty.Register
        (
            "UnselectedImage",
            typeof(string),
            typeof(TabHeader),
            null
        );

        #endregion
        #region 레이블 속성 - LabelProperty

        /// <summary>
        /// 레이블 속성
        /// </summary>
        public static readonly DependencyProperty LabelProperty = DependencyProperty.Register
        (
            "Label",
            typeof(string),
            typeof(TabHeader),
            null
        );

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 선택 이미지 - SelectedImage

        /// <summary>
        /// 선택 이미지
        /// </summary>
        public string SelectedImage
        {
            get
            {
                return (string)GetValue(SelectedImageProperty);
            }
            set
            {
                SetValue(SelectedImageProperty, value);
            }
        }

        #endregion
        #region 미선택 이미지 - UnselectedImage

        /// <summary>
        /// 미선택 이미지
        /// </summary>
        public string UnselectedImage
        {
            get
            {
                return (string)GetValue(UnselectedImageProperty);
            }
            set
            {
                SetValue(UnselectedImageProperty, value);
            }
        }

        #endregion
        #region 레이블 - Label

        /// <summary>
        /// 레이블
        /// </summary>
        public string Label
        {
            get
            {
                return (string)GetValue(LabelProperty);
            }
            set
            {
                SetValue(LabelProperty, value);
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - TabHeader()

        /// <summary>
        /// 생성자
        /// </summary>
        public TabHeader()
        {
            InitializeComponent();

            DataContext = this;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 선택 항목 설정하기 - SetSelectedItem(selected)

        /// <summary>
        /// 선택 항목 설정하기
        /// </summary>
        /// <param name="selected">선택 여부</param>
        public void SetSelectedItem(bool selected)
        {
            switch(selected)
            {
                case true :

                    this.selectedImage.Visibility   = Visibility.Visible;
                    this.unselectedImage.Visibility = Visibility.Collapsed;

                    break;

                case false :

                    this.selectedImage.Visibility   = Visibility.Collapsed;
                    this.unselectedImage.Visibility = Visibility.Visible;

                    break;
            }
        }

        #endregion
    }
}

 

300x250

 

▶ 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
    }
}

 

▶ CPUTimeConverter.cs

using System;
using Windows.UI.Xaml.Data;

namespace TestProject
{
    /// <summary>
    /// CPU 시간 변환자
    /// </summary>
    public class CPUTimeConverter : 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;

            TimeSpan timeSpan = (TimeSpan)sourceValue;

            if(timeSpan != TimeSpan.MinValue)
            {
                targetValue = $"{sourceValue:h\\:mm\\:ss}";
            }

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

 

▶ StringFormatConverter.cs

using System;
using Windows.UI.Xaml.Data;

namespace TestProject
{
    /// <summary>
    /// 문자열 포맷 변환자
    /// </summary>
    public sealed class StringFormatConverter : 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;
            }

            if(parameter == null)
            {
                return sourceValue;
            }

            return string.Format((string)parameter, sourceValue);
        }

        #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
    }
}

 

▶ ACLineStatus.cs

namespace TestProject
{
    /// <summary>
    /// 직렬 라인 상태
    /// </summary>
    public enum ACLineStatus : byte
    {
        /// <summary>
        /// 오프라인
        /// </summary>
        Offline = 0,

        /// <summary>
        /// 온라인
        /// </summary>
        Online = 1,

        /// <summary>
        /// 알 수 없음
        /// </summary>
        Unknown = 255
    }
}

 

▶ BatteryFlag.cs

using System;

namespace TestProject
{
    /// <summary>
    /// 배터리 플래그
    /// </summary>
    [Flags]
    public enum BatteryFlag : byte
    {
        /// <summary>
        /// 높음
        /// </summary>
        High = 1,

        /// <summary>
        /// 낮음
        /// </summary>
        Low = 2,

        /// <summary>
        /// 위기
        /// </summary>
        Critical = 4,

        /// <summary>
        /// 충전중
        /// </summary>
        Charging = 8,

        /// <summary>
        /// 시스템 배터리 없음
        /// </summary>
        NoSystemBattery = 128,

        /// <summary>
        /// 알 수 없음
        /// </summary>
        Unknown = 255
    }
}

 

▶ 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
    }
}

 

▶ 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
    }
}

 

▶ IANAInterfaceType.cs

namespace TestProject
{
    /// <summary>
    /// IANA 인터페이스 타입
    /// </summary>
    public enum IANAInterfaceType
    {
        other = 1,
        regular1822 = 2,
        hdh1822 = 3,
        ddnX25 = 4,
        rfc877x25 = 5,
        ethernetCsmacd = 6,
        iso88023Csmacd = 7,
        iso88024TokenBus = 8,
        iso88025TokenRing = 9,
        iso88026Man = 10,
        starLan = 11,
        proteon10Mbit = 12,
        proteon80Mbit = 13,
        hyperchannel = 14,
        fddi = 15,
        lapb = 16,
        sdlc = 17,
        ds1 = 18,
        e1 = 19,
        basicISDN = 20,
        primaryISDN = 21,
        propPointToPointSerial = 22,
        ppp = 23,
        softwareLoopback = 24,
        eon = 25,
        ethernet3Mbit = 26,
        nsip = 27,
        slip = 28,
        ultra = 29,
        ds3 = 30,
        sip = 31,
        frameRelay = 32,
        rs232 = 33,
        para = 34,
        arcnet = 35,
        arcnetPlus = 36,
        atm = 37,
        miox25 = 38,
        sonet = 39,
        x25ple = 40,
        iso88022llc = 41,
        localTalk = 42,
        smdsDxi = 43,
        frameRelayService = 44,
        v35 = 45,
        hssi = 46,
        hippi = 47,
        modem = 48,
        aal5 = 49,
        sonetPath = 50,
        sonetVT = 51,
        smdsIcip = 52,
        propVirtual = 53,
        propMultiplexor = 54,
        ieee80212 = 55,
        fibreChannel = 56,
        hippiInterface = 57,
        frameRelayInterconnect = 58,
        aflane8023 = 59,
        aflane8025 = 60,
        cctEmul = 61,
        fastEther = 62,
        isdn = 63,
        v11 = 64,
        v36 = 65,
        g703at64k = 66,
        g703at2mb = 67,
        qllc = 68,
        fastEtherFX = 69,
        channel = 70,
        ieee80211 = 71,
        ibm370parChan = 72,
        escon = 73,
        dlsw = 74,
        isdns = 75,
        isdnu = 76,
        lapd = 77,
        ipSwitch = 78,
        rsrb = 79,
        atmLogical = 80,
        ds0 = 81,
        ds0Bundle = 82,
        bsc = 83,
        async = 84,
        cnr = 85,
        iso88025Dtr = 86,
        eplrs = 87,
        arap = 88,
        propCnls = 89,
        hostPad = 90,
        termPad = 91,
        frameRelayMPI = 92,
        x213 = 93,
        adsl = 94,
        radsl = 95,
        sdsl = 96,
        vdsl = 97,
        iso88025CRFPInt = 98,
        myrinet = 99,
        voiceEM = 100,
        voiceFXO = 101,
        voiceFXS = 102,
        voiceEncap = 103,
        voiceOverIp = 104,
        atmDxi = 105,
        atmFuni = 106,
        atmIma = 107,
        pppMultilinkBundle = 108,
        ipOverCdlc = 109,
        ipOverClaw = 110,
        stackToStack = 111,
        virtualIpAddress = 112,
        mpc = 113,
        ipOverAtm = 114,
        iso88025Fiber = 115,
        tdlc = 116,
        gigabitEthernet = 117,
        hdlc = 118,
        lapf = 119,
        v37 = 120,
        x25mlp = 121,
        x25huntGroup = 122,
        transpHdlc = 123,
        interleave = 124,
        fast = 125,
        ip = 126,
        docsCableMaclayer = 127,
        docsCableDownstream = 128,
        docsCableUpstream = 129,
        a12MppSwitch = 130,
        tunnel = 131,
        coffee = 132,
        ces = 133,
        atmSubInterface = 134,
        l2vlan = 135,
        l3ipvlan = 136,
        l3ipxvlan = 137,
        digitalPowerline = 138,
        mediaMailOverIp = 139,
        dtm = 140,
        dcn = 141,
        ipForward = 142,
        msdsl = 143,
        ieee1394 = 144,
        ifgsn = 145,
        dvbRccMacLayer = 146,
        dvbRccDownstream = 147,
        dvbRccUpstream = 148,
        atmVirtual = 149,
        mplsTunnel = 150,
        srp = 151,
        voiceOverAtm = 152,
        voiceOverFrameRelay = 153,
        idsl = 154,
        compositeLink = 155,
        ss7SigLink = 156,
        propWirelessP2P = 157,
        frForward = 158,
        rfc1483 = 159,
        usb = 160,
        ieee8023adLag = 161,
        bgppolicyaccounting = 162,
        frf16MfrBundle = 163,
        h323Gatekeeper = 164,
        h323Proxy = 165,
        mpls = 166,
        mfSigLink = 167,
        hdsl2 = 168,
        shdsl = 169,
        ds1FDL = 170,
        pos = 171,
        dvbAsiIn = 172,
        dvbAsiOut = 173,
        plc = 174,
        nfas = 175,
        tr008 = 176,
        gr303RDT = 177,
        gr303IDT = 178,
        isup = 179,
        propDocsWirelessMaclayer = 180,
        propDocsWirelessDownstream = 181,
        propDocsWirelessUpstream = 182,
        hiperlan2 = 183,
        propBWAp2Mp = 184,
        sonetOverheadChannel = 185,
        digitalWrapperOverheadChannel = 186,
        aal2 = 187,
        radioMAC = 188,
        atmRadio = 189,
        imt = 190,
        mvl = 191,
        reachDSL = 192,
        frDlciEndPt = 193,
        atmVciEndPt = 194,
        opticalChannel = 195,
        opticalTransport = 196,
        propAtm = 197,
        voiceOverCable = 198,
        infiniband = 199,
        teLink = 200,
        q2931 = 201,
        virtualTg = 202,
        sipTg = 203,
        sipSig = 204,
        docsCableUpstreamChannel = 205,
        econet = 206,
        pon155 = 207,
        pon622 = 208,
        bridge = 209,
        linegroup = 210,
        voiceEMFGD = 211,
        voiceFGDEANA = 212,
        voiceDID = 213,
        mpegTransport = 214,
        sixToFour = 215,
        gtp = 216,
        pdnEtherLoop1 = 217,
        pdnEtherLoop2 = 218,
        opticalChannelGroup = 219,
        homepna = 220,
        gfp = 221,
        ciscoISLvlan = 222,
        actelisMetaLOOP = 223,
        fcipLink = 224,
        rpr = 225,
        qam = 226,
        lmp = 227,
        cblVectaStar = 228,
        docsCableMCmtsDownstream = 229,
        adsl2 = 230,
        macSecControlledIF = 231,
        macSecUncontrolledIF = 232,
        aviciOpticalEther = 233,
        atmbond = 234,
        voiceFGDOS = 235,
        mocaVersion1 = 236,
        ieee80216WMAN = 237,
        adsl2plus = 238,
        dvbRcsMacLayer = 239,
        dvbTdm = 240,
        dvbRcsTdma = 241,
        x86Laps = 242,
        wwanPP = 243,
        wwanPP2 = 244,
        voiceEBS = 245,
        ifPwType = 246,
        ilan = 247,
        pip = 248,
        aluELP = 249,
        gpon = 250,
        vdsl2 = 251,
        capwapDot11Profile = 252,
        capwapDot11Bss = 253,
        capwapWtpVirtualRadio = 254,
        bits = 255,
        docsCableUpstreamRfPort = 256,
        cableDownstreamRfPort = 257,
        vmwareVirtualNic = 258,
        ieee802154 = 259,
        otnOdu = 260,
        otnOtu = 261,
        ifVfiType = 262,
        g9981 = 263,
        g9982 = 264,
        g9983 = 265,
        aluEpon = 266,
        aluEponOnu = 267,
        aluEponPhysicalUni = 268,
        aluEponLogicalLink = 269,
        aluGponOnu = 270,
        aluGponPhysicalUni = 271,
        vmwareNicTeam = 272,
        docsOfdmDownstream = 277,
        docsOfdmaUpstream = 278,
        gfast = 279,
        sdci = 280,
        xboxWireless = 281,
        fastdsl = 282,
        docsCableScte55d1FwdOob = 283,
        docsCableScte55d1RetOob = 284,
        docsCableScte55d2DsOob = 285,
        docsCableScte55d2UsOob = 286,
        docsCableNdf = 287,
        docsCableNdr = 288,
        ptm = 289,
        ghn = 290,
    }
}

 

▶ LOGICAL_PROCESSOR_RELATIONSHIP.cs

namespace TestProject
{
    /// <summary>
    /// 논리적 프로세서 관계
    /// </summary>
    public enum LOGICAL_PROCESSOR_RELATIONSHIP
    {
        /// <summary>
        /// RelationProcessorCore
        /// </summary>
        RelationProcessorCore,

        /// <summary>
        /// RelationNumaNode
        /// </summary>
        RelationNumaNode,

        /// <summary>
        /// RelationCache
        /// </summary>
        RelationCache,

        /// <summary>
        /// RelationProcessorPackage
        /// </summary>
        RelationProcessorPackage,

        /// <summary>
        /// RelationGroup
        /// </summary>
        RelationGroup,

        /// <summary>
        /// RelationAll
        /// </summary>
        RelationAll = 0xffff
    }
}

 

▶ PROCESSOR_CACHE_TYPE.cs

namespace TestProject
{
    /// <summary>
    /// 프로세서 캐시 타입
    /// </summary>
    public enum PROCESSOR_CACHE_TYPE
    {
        /// <summary>
        /// CacheUnified
        /// </summary>
        CacheUnified,

        /// <summary>
        /// CacheInstruction
        /// </summary>
        CacheInstruction,

        /// <summary>
        /// CacheData
        /// </summary>
        CacheData,

        /// <summary>
        /// CacheTrace
        /// </summary>
        CacheTrace
    }
}

 

▶ ProcessorArchitecture.cs

namespace TestProject
{
    /// <summary>
    /// 프로세서 아키텍처
    /// </summary>
    public enum ProcessorArchitecture : ushort
    {
        /// <summary>
        /// Intel
        /// </summary>
        Intel = 0,

        /// <summary>
        /// IA64
        /// </summary>
        IA64 = 6,

        /// <summary>
        /// AMD64
        /// </summary>
        AMD64 = 9,

        /// <summary>
        /// Unknown
        /// </summary>
        Unknown = 0xffff
    }
}

 

▶ ProcessorFeature.cs

namespace TestProject
{
    /// <summary>
    /// 프로세서 특징
    /// </summary>
    public enum ProcessorFeature : uint
    {
        /// <summary>
        /// On a Pentium, a floating-point precision error can occur in rare circumstances
        /// </summary>
        FloatingPointPrecisionErrata = 0,

        /// <summary>
        /// Floating-point operations are emulated using a software emulator. 
        /// This function returns a nonzero value if floating-point operations are emulated; otherwise, it returns zero.
        /// </summary>
        FloatingPointEmulated = 1,

        /// <summary>
        /// The atomic compare and exchange operation (cmpxchg) is available
        /// </summary>
        CompareExchangeDouble = 2,

        /// <summary>
        /// The MMX instruction set is available
        /// </summary>
        InstructionsMMXAvailable = 3,

        /// <summary>
        /// The SSE instruction set is available
        /// </summary>
        InstructionsXMMIAvailable = 6,

        /// <summary>
        /// The 3D-Now instruction set is available.
        /// </summary>
        Instruction3DNowAvailable = 7,

        /// <summary>
        /// The RDTSC instruction is available
        /// </summary>
        InstructionRDTSCAvailable = 8,

        /// <summary>
        /// The processor is PAE-enabled
        /// </summary>
        PAEEnabled = 9,

        /// <summary>
        /// The SSE2 instruction set is available
        /// </summary>
        InstructionsXMMI64Available = 10,

        /// <summary>
        /// Data execution prevention is enabled.
        /// (This feature is not supported until Windows XP SP2 and Windows Server 2003 SP1)
        /// </summary>
        NXEnabled = 12,

        /// <summary>
        /// The SSE3 instruction set is available.
        /// (This feature is not supported until Windows Vista)
        /// </summary>
        InstructionsSSE3Available = 13,

        /// <summary>
        /// The atomic compare and exchange 128-bit operation (cmpxchg16b) is available.
        /// (This feature is not supported until Windows Vista)
        /// </summary>
        CompareExchange128 = 14,

        /// <summary>
        /// The atomic compare 64 and exchange 128-bit operation (cmp8xchg16) is available.
        /// (This feature is not supported until Windows Vista.)
        /// </summary>
        Compare64Exchange128 = 15,

        /// <summary>
        /// TBD
        /// </summary>
        ChannelsEnabled = 16
    }
}

 

▶ SystemStatusFlag.cs

namespace TestProject
{
    /// <summary>
    /// 시스템 상태 플래그
    /// </summary>
    public enum SystemStatusFlag : byte
    {
        /// <summary>
        /// OFF
        /// </summary>
        Off = 0,

        /// <summary>
        /// ON
        /// </summary>
        On = 1
    }
}

 

▶ WIN32Helper.cs

using System;
using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// WIN32 헬퍼
    /// </summary>
    public class WIN32Helper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 논리적 프로세서 정보 구하기 - GetLogicalProcessorInformation(bufferHandle, returnLength)

        /// <summary>
        /// 논리적 프로세서 정보 구하기
        /// </summary>
        /// <param name="bufferHandle">버퍼 핸들</param>
        /// <param name="bufferLength">버퍼 길이</param>
        /// <returns>처리 결과</returns>
        [DllImport("kernel32", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetLogicalProcessorInformation(IntPtr bufferHandle, ref uint bufferLength);

        #endregion
        #region 프로세서 특징 존재 여부 구하기 - IsProcessorFeaturePresent(processorFeature)

        /// <summary>
        /// 프로세서 특징 존재 여부 구하기
        /// </summary>
        /// <param name="processorFeature">프로세서 특징</param>
        /// <returns>프로세서 특징 존재 여부</returns>
        [DllImport("kernel32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsProcessorFeaturePresent(ProcessorFeature processorFeature);

        #endregion
        #region 시스템 정보 구하기 - GetSystemInfo(systemInformation)

        /// <summary>
        /// 시스템 정보 구하기
        /// </summary>
        /// <param name="systemInformation">시스템 정보</param>
        [DllImport("kernel32")]
        public static extern void GetSystemInfo(ref SYSTEM_INFORMATION systemInformation);

        #endregion
        #region 전역 메모리 상태 구하기 (확장) - GlobalMemoryStatusEx(memoryStatus)

        /// <summary>
        /// 전역 메모리 상태 구하기 (확장)
        /// </summary>
        /// <param name="memoryStatus">메모리 상태</param>
        /// <returns>처리 결과</returns>
        [DllImport("kernel32", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX memoryStatus);

        #endregion
        #region 시스템 전원 상태 구하기 - GetSystemPowerStatus(systemPowerStatus)

        /// <summary>
        /// 시스템 전원 상태 구하기
        /// </summary>
        /// <param name="systemPowerStatus">시스템 전원 상태</param>
        /// <returns>처리 결과</returns>
        [DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetSystemPowerStatus(ref SYSTEM_POWER_STATUS systemPowerStatus);

        #endregion
        #region 디스크 자유 공간 구하기 (확장) - GetDiskFreeSpaceEx(directoryName, userFreeByteCount, userTotalByteCount, totalFreeByteCount)

        /// <summary>
        /// 디스크 자유 공간 구하기 (확장)
        /// </summary>
        /// <param name="directoryName">디렉토리명</param>
        /// <param name="userFreeByteCount">사용자 잔여 바이트 카운트</param>
        /// <param name="userTotalByteCount">사용자 전체 바이트 카운트</param>
        /// <param name="totalFreeByteCount">전체 잔여 바이트 카운트</param>
        /// <returns>처리 결과</returns>
        [DllImport("kernel32", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetDiskFreeSpaceEx(string directoryName, out ulong userFreeByteCount, out ulong userTotalByteCount, out ulong totalFreeByteCount);

        #endregion
        #region 네트워크 매개 변수 구하기 - GetNetworkParams(fixedInformationHandle, bufferLength)

        /// <summary>
        /// 네트워크 매개 변수 구하기
        /// </summary>
        /// <param name="fixedInformationHandle">고정 정보 핸들</param>
        /// <param name="bufferLength">버퍼 길이</param>
        /// <returns>처리 결과</returns>
        [DllImport("iphlpapi", CharSet = CharSet.Ansi)]
        public static extern int GetNetworkParams(IntPtr fixedInformationHandle, ref uint bufferLength);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// ERROR_INSUFFICIENT_BUFFER
        /// </summary>
        private const int ERROR_INSUFFICIENT_BUFFER = 122;

        /// <summary>
        /// MAXIMUM_HOSTNAME_LENGTH
        /// </summary>
        public const int MAXIMUM_HOSTNAME_LENGTH = 128;

        /// <summary>
        /// MAXIMUM_SCOPE_ID_LENGTH
        /// </summary>
        public const int MAXIMUM_SCOPE_ID_LENGTH = 256;

        /// <summary>
        /// ERROR_SUCCESS
        /// </summary>
        public const int ERROR_SUCCESS = 0;

        /// <summary>
        /// ERROR_BUFFER_OVERFLOW
        /// </summary>
        public const int ERROR_BUFFER_OVERFLOW = 111;

        /// <summary>
        /// BROADCAST_NODETYPE
        /// </summary>
        public const int BROADCAST_NODETYPE = 1;

        /// <summary>
        /// PEER_TO_PEER_NODETYPE
        /// </summary>
        public const int PEER_TO_PEER_NODETYPE = 2;

        /// <summary>
        /// MIXED_NODETYPE
        /// </summary>
        public const int MIXED_NODETYPE = 4;

        /// <summary>
        /// HYBRID_NODETYPE
        /// </summary>
        public const int HYBRID_NODETYPE = 8;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 논리적 프로세서 정보 구하기 - GetLogicalProcessorInformation()

        /// <summary>
        /// 논리적 프로세서 정보 구하기
        /// </summary>
        /// <returns>시스템 논리적 프로세서 정보 배열</returns>
        public static SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] GetLogicalProcessorInformation()
        {
            uint bufferLength = 0;

            GetLogicalProcessorInformation(IntPtr.Zero, ref bufferLength);

            if(Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
            {
                IntPtr bufferHandle = Marshal.AllocHGlobal((int)bufferLength);

                try
                {
                    if(GetLogicalProcessorInformation(bufferHandle, ref bufferLength))
                    {
                        int size = Marshal.SizeOf<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>();

                        int length = (int)bufferLength / size;

                        SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] targetArray = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[length];

                        IntPtr itemHandle = bufferHandle;

                        for(int i = 0; i < length; i++)
                        {
                            targetArray[i] = Marshal.PtrToStructure<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>(itemHandle);

                            itemHandle += size;
                        }

                        return targetArray;
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(bufferHandle);
                }
            }

            return null;
        }

        #endregion
    }
}

 

▶ 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
    }
}

 

▶ AppCollection.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.Media.Imaging;

namespace TestProject
{
    /// <summary>
    /// 앱 컬렉션
    /// </summary>
    public class AppCollection : ObservableCollection<AppModel>
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 잠금 객체
        /// </summary>
        private static readonly object _lockObject = new object();

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 정렬 순서 딕셔너리
        /// </summary>
        private Dictionary<string, bool> sortOrderDictionary = new Dictionary<string, bool>();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - AppCollection()

        /// <summary>
        /// 생성자
        /// </summary>
        public AppCollection()
        {
            this.sortOrderDictionary.Add("Name"               , true );
            this.sortOrderDictionary.Add("CommitLimit"        , false);
            this.sortOrderDictionary.Add("TotalCommit"        , false);
            this.sortOrderDictionary.Add("PrivateCommit"      , false);
            this.sortOrderDictionary.Add("ExecutionState"     , false);
            this.sortOrderDictionary.Add("EnergyQuotaState"   , false);
            this.sortOrderDictionary.Add("BackgroundTaskCount", false);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 액세스 상태 구하기 (비동기) - GetAccessStatusAsync()

        /// <summary>
        /// 액세스 상태 구하기 (비동기)
        /// </summary>
        /// <returns>액세스 상태 태스크</returns>
        public async Task<DiagnosticAccessStatus> GetAccessStatusAsync()
        {
            DiagnosticAccessStatus accessStatus = await AppDiagnosticInfo.RequestAccessAsync();

            return accessStatus;
        }

        #endregion
        #region 업데이트하기 - Update()

        /// <summary>
        /// 업데이트하기
        /// </summary>
        /// <returns>처리 결과</returns>
        public bool Update()
        {
            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
        #region 앱 프로세스 태스크 구하기 - GetAppProcesseTask(app)

        /// <summary>
        /// 앱 프로세스 태스크 구하기
        /// </summary>
        /// <param name="app">앱</param>
        /// <returns>앱 프로세스 태스크</returns>
        public AppProcessTaskModel GetAppProcesseTask(AppModel app)
        {
            AppProcessTaskModel appProcesseTask = null;

            List<ProcessDetailModel> processDetailList = new List<ProcessDetailModel>();

            List<AppResourceGroupBackgroundTaskReport> appResourceGroupBackgroundTaskReportList = new List<AppResourceGroupBackgroundTaskReport>();

            AppDetailModel appDetail = GetAppDetail(app);

            if(appDetail != null)
            {
                if(appDetail.GroupDetailList != null && appDetail.GroupDetailList.Count > 0)
                {
                    foreach(GroupDetailModel groupDetail in appDetail.GroupDetailList)
                    {
                        if(groupDetail.ProcessDetailList != null && groupDetail.ProcessDetailList.Count > 0)
                        {
                            foreach(ProcessDetailModel processDetail in groupDetail.ProcessDetailList)
                            {
                                processDetailList.Add(processDetail);
                            }
                        }

                        if(groupDetail.AppResourceGroupBackgroundTaskReportList != null && groupDetail.AppResourceGroupBackgroundTaskReportList.Count > 0)
                        {
                            foreach(AppResourceGroupBackgroundTaskReport appResourceGroupBackgroundTaskReport in groupDetail.AppResourceGroupBackgroundTaskReportList)
                            {
                                appResourceGroupBackgroundTaskReportList.Add(appResourceGroupBackgroundTaskReport);
                            }
                        }
                    }
                }

                appProcesseTask = new AppProcessTaskModel()
                {
                    AppDetail                                = appDetail,
                    AppResourceGroupBackgroundTaskReportList = appResourceGroupBackgroundTaskReportList,
                    ProcessDetailList                        = processDetailList
                };
            }

            return appProcesseTask;
        }

        #endregion
        #region 정렬하기 - Sort(column, isUserAction)

        /// <summary>
        /// 정렬하기
        /// </summary>
        /// <param name="column">컬럼</param>
        /// <param name="isUserAction">사용자 액션 여부</param>
        public void Sort(string column, bool isUserAction)
        {
            List<AppModel> targetList = null;

            switch(column)
            {
                case "Name"                : targetList = this.OrderBy(a => a.Name               ).ToList(); break;
                case "CommitLimit"         : targetList = this.OrderBy(a => a.CommitLimit        ).ToList(); break;
                case "TotalCommit"         : targetList = this.OrderBy(a => a.TotalCommit        ).ToList(); break;
                case "PrivateCommit"       : targetList = this.OrderBy(a => a.PrivateCommit      ).ToList(); break;
                case "ExecutionState"      : targetList = this.OrderBy(a => a.ExecutionState     ).ToList(); break;
                case "EnergyQuotaState"    : targetList = this.OrderBy(a => a.EnergyQuotaState   ).ToList(); break;
                case "BackgroundTaskCount" : targetList = this.OrderBy(a => a.BackgroundTaskCount).ToList(); break;
            }

            KeyValuePair<string, bool> keyValuePair = this.sortOrderDictionary.FirstOrDefault(i => i.Key == column);

            bool isAscending = keyValuePair.Value;

            if(isUserAction)
            {
                isAscending = !isAscending;

                this.sortOrderDictionary[column] = isAscending;
            }

            if(isAscending == false)
            {
                targetList.Reverse();
            }

            for(int i = 0; i < targetList.Count(); i++)
            {
                Move(IndexOf(targetList[i]), i);
            }
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 죽은 행 제거하기 - RemoveDeadRows(adiList)

        /// <summary>
        /// 죽은 행 제거하기
        /// </summary>
        /// <param name="adiList">앱 진단 정보 리스트</param>
        private void RemoveDeadRows(IList<AppDiagnosticInfo> adiList)
        {
            for(int i = 0; i < Count; i++)
            {
                bool isFound = false;

                AppModel app = this[i];

                foreach(AppDiagnosticInfo adi in adiList)
                {
                    if(adi.AppInfo.AppUserModelId == app.ID)
                    {
                        isFound = true;
                    }
                }

                if(!isFound)
                {
                    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)
            {
                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
                );

                Add(app);

                result = true;
            }
            else
            {
                IEnumerable<AppModel> appEnumerable = this.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 앱 상세 구하기 - GetAppDetail(app)

        /// <summary>
        /// 앱 상세 구하기
        /// </summary>
        /// <param name="app">앱</param>
        /// <returns>앱 상세</returns>
        private AppDetailModel GetAppDetail(AppModel app)
        {
            AppDetailModel appDetail = null;

            try
            {
                IList<GroupDetailModel> groupDetailList = new List<GroupDetailModel>();

                IList<AppResourceGroupInfo> appResourceGroupInfoList = app.ADI.GetResourceGroups();

                if(appResourceGroupInfoList != null && appResourceGroupInfoList.Count > 0)
                {
                    foreach(AppResourceGroupInfo appResourceGroupInfo in appResourceGroupInfoList)
                    {
                        IList<ProcessDetailModel> processDetailList = new List<ProcessDetailModel>();

                        IList<ProcessDiagnosticInfo> processDiagnosticInfoList = appResourceGroupInfo.GetProcessDiagnosticInfos();

                        if(processDiagnosticInfoList != null && processDiagnosticInfoList.Count > 0)
                        {
                            foreach(ProcessDiagnosticInfo processDiagnosticInfo in processDiagnosticInfoList)
                            {
                                TimeSpan kernelTimeSpan = TimeSpan.Zero;
                                TimeSpan userTimeSpan   = TimeSpan.Zero;

                                ulong nonPagedPoolSizeInByteCount      = 0;
                                ulong pagedPoolSizeInByteCount         = 0;
                                ulong pageFaultCount                   = 0;
                                ulong pageFileSizeInByteCount          = 0;
                                ulong peakNonPagedPoolSizeInByteCount  = 0;
                                ulong peakPagedPoolSizeInByteCount     = 0;
                                ulong peakPageFileSizeInByteCount      = 0;
                                ulong peakVirtualMemorySizeInByteCount = 0;
                                ulong peakWorkingSetSizeInByteCount    = 0;
                                ulong privatePageCount                 = 0;
                                ulong virtualMemorySizeInByteCount     = 0;
                                ulong workingSetSizeInByteCount        = 0;

                                long readByteCount = 0;
                                long writeByteCount = 0;
                                long otherByteCount = 0;
                                long otherOperationCount = 0;
                                long readOperationCount = 0;
                                long writeOperationCount = 0;

                                ProcessCpuUsageReport processCpuUsageReport = processDiagnosticInfo.CpuUsage.GetReport();

                                if(processCpuUsageReport != null)
                                {
                                    kernelTimeSpan = processCpuUsageReport.KernelTime;
                                    userTimeSpan   = processCpuUsageReport.UserTime;
                                }

                                ProcessMemoryUsageReport processMemoryUsageReport = processDiagnosticInfo.MemoryUsage.GetReport();

                                if(processMemoryUsageReport != null)
                                {
                                    nonPagedPoolSizeInByteCount      = processMemoryUsageReport.NonPagedPoolSizeInBytes;
                                    pagedPoolSizeInByteCount         = processMemoryUsageReport.PagedPoolSizeInBytes;
                                    pageFaultCount                   = processMemoryUsageReport.PageFaultCount;
                                    pageFileSizeInByteCount          = processMemoryUsageReport.PageFileSizeInBytes;
                                    peakNonPagedPoolSizeInByteCount  = processMemoryUsageReport.PeakNonPagedPoolSizeInBytes;
                                    peakPagedPoolSizeInByteCount     = processMemoryUsageReport.PeakPagedPoolSizeInBytes;
                                    peakPageFileSizeInByteCount      = processMemoryUsageReport.PeakPageFileSizeInBytes;
                                    peakVirtualMemorySizeInByteCount = processMemoryUsageReport.PeakVirtualMemorySizeInBytes;
                                    peakWorkingSetSizeInByteCount    = processMemoryUsageReport.PeakWorkingSetSizeInBytes;
                                    privatePageCount                 = processMemoryUsageReport.PrivatePageCount;
                                    virtualMemorySizeInByteCount     = processMemoryUsageReport.VirtualMemorySizeInBytes;
                                    workingSetSizeInByteCount        = processMemoryUsageReport.WorkingSetSizeInBytes;
                                }

                                ProcessDiskUsageReport processDiskUsageReport = processDiagnosticInfo.DiskUsage.GetReport();

                                if(processDiskUsageReport != null)
                                {
                                    readByteCount       = processDiskUsageReport.BytesReadCount;
                                    writeByteCount      = processDiskUsageReport.BytesWrittenCount;
                                    otherByteCount      = processDiskUsageReport.OtherBytesCount;
                                    otherOperationCount = processDiskUsageReport.OtherOperationCount;
                                    readOperationCount  = processDiskUsageReport.ReadOperationCount;
                                    writeOperationCount = processDiskUsageReport.WriteOperationCount;
                                }

                                ProcessDetailModel processDetailModel = new ProcessDetailModel
                                (
                                    processDiagnosticInfo.ProcessId,
                                    processDiagnosticInfo.ExecutableFileName,
                                    processDiagnosticInfo.ProcessStartTime,
                                    kernelTimeSpan,
                                    userTimeSpan,
                                    nonPagedPoolSizeInByteCount,
                                    pagedPoolSizeInByteCount,
                                    pageFaultCount,
                                    pageFileSizeInByteCount,
                                    peakNonPagedPoolSizeInByteCount,
                                    peakPagedPoolSizeInByteCount,
                                    peakPageFileSizeInByteCount,
                                    peakVirtualMemorySizeInByteCount,
                                    peakWorkingSetSizeInByteCount,
                                    privatePageCount,
                                    virtualMemorySizeInByteCount,
                                    workingSetSizeInByteCount,
                                    readByteCount,
                                    writeByteCount,
                                    otherByteCount,
                                    otherOperationCount,
                                    readOperationCount,
                                    writeOperationCount
                                );

                                processDetailList.Add(processDetailModel);
                            }
                        }

                        AppMemoryUsageLevel appMemoryUsageLevel = AppMemoryUsageLevel.Low;

                        ulong commitLimit   = 0;
                        ulong privateCommit = 0;
                        ulong totalCommit   = 0;

                        AppResourceGroupExecutionState   appResourceGroupExecutionState   = AppResourceGroupExecutionState.Unknown;
                        AppResourceGroupEnergyQuotaState appResourceGroupEnergyQuotaState = AppResourceGroupEnergyQuotaState.Unknown;

                        AppResourceGroupMemoryReport appResourceGroupMemoryReport = appResourceGroupInfo.GetMemoryReport();
                        AppResourceGroupStateReport  appResourceGroupStateReport  = appResourceGroupInfo.GetStateReport();

                        IList<AppResourceGroupBackgroundTaskReport> appResourceGroupBackgroundTaskReportList = new List<AppResourceGroupBackgroundTaskReport>();

                        appResourceGroupBackgroundTaskReportList = appResourceGroupInfo.GetBackgroundTaskReports();

                        if(appResourceGroupMemoryReport != null)
                        {
                            appMemoryUsageLevel = appResourceGroupMemoryReport.CommitUsageLevel;
                            commitLimit         = appResourceGroupMemoryReport.CommitUsageLimit;
                            privateCommit       = appResourceGroupMemoryReport.PrivateCommitUsage;
                            totalCommit         = appResourceGroupMemoryReport.TotalCommitUsage;
                        }

                        if(appResourceGroupStateReport != null)
                        {
                            appResourceGroupExecutionState   = appResourceGroupStateReport.ExecutionState;
                            appResourceGroupEnergyQuotaState = appResourceGroupStateReport.EnergyQuotaState;
                        }

                        GroupDetailModel groupDetail = new GroupDetailModel
                        (
                            appResourceGroupInfo.InstanceId,
                            appResourceGroupInfo.IsShared,
                            appMemoryUsageLevel,
                            commitLimit,
                            privateCommit,
                            totalCommit,
                            appResourceGroupExecutionState,
                            appResourceGroupEnergyQuotaState,
                            appResourceGroupBackgroundTaskReportList,
                            processDetailList
                        );

                        groupDetailList.Add(groupDetail);
                    }

                    appDetail = new AppDetailModel
                    (
                        app.Logo,
                        app.ADI.AppInfo.AppUserModelId,
                        app.ADI.AppInfo.Id,
                        app.ADI.AppInfo.PackageFamilyName,
                        app.ADI.AppInfo.DisplayInfo.DisplayName,
                        app.ADI.AppInfo.DisplayInfo.Description,
                        groupDetailList
                    );
                }
            }
            catch
            {
            }

            return appDetail;
        }

        #endregion
    }
}

 

▶ AppDetailModel.cs

using System.Collections.Generic;
using Windows.UI.Xaml.Media.Imaging;

namespace TestProject
{
    /// <summary>
    /// 앱 상세 모델
    /// </summary>
    public class AppDetailModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 로고 - Logo

        /// <summary>
        /// 로고
        /// </summary>
        public BitmapImage Logo { get; internal set; }

        #endregion
        #region 앱 사용자 모델 ID - AppUserModelID

        /// <summary>
        /// 앱 사용자 모델 ID
        /// </summary>
        public string AppUserModelID { get; internal set; }

        #endregion
        #region ID - ID

        /// <summary>
        /// ID
        /// </summary>
        public string ID { get; internal set; }

        #endregion
        #region 패키지 패밀리명 - PackageFamilyName

        /// <summary>
        /// 패키지 패밀리명
        /// </summary>
        public string PackageFamilyName { get; internal set; }

        #endregion
        #region 디스플레이명 - DisplayName

        /// <summary>
        /// 디스플레이명
        /// </summary>
        public string DisplayName { get; internal set; }

        #endregion
        #region 설명 - Description

        /// <summary>
        /// 설명
        /// </summary>
        public string Description { get; internal set; }

        #endregion
        #region 그룹 상세 리스트 - GroupDetailList

        /// <summary>
        /// 그룹 상세 리스트
        /// </summary>
        public IList<GroupDetailModel> GroupDetailList { get; internal set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - AppDetailModel(logo, appUserModelID, id, packageFamilyName, name, description, groupDetailList)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="logo">로고</param>
        /// <param name="appUserModelID">앱 사용자 모델 ID</param>
        /// <param name="id">ID</param>
        /// <param name="packageFamilyName">패키지 패밀리명</param>
        /// <param name="name">명칭</param>
        /// <param name="description">설명</param>
        /// <param name="groupDetailList">그룹 상세 리스트</param>
        public AppDetailModel
        (
            BitmapImage             logo,
            string                  appUserModelID,
            string                  id,
            string                  packageFamilyName,
            string                  name,
            string                  description,
            IList<GroupDetailModel> groupDetailList
        )
        {
            Logo              = logo;
            AppUserModelID    = appUserModelID;
            ID                = id;
            PackageFamilyName = packageFamilyName;
            DisplayName       = name;
            Description       = description;
            GroupDetailList   = groupDetailList;
        }

        #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
    }
}

 

▶ AppProcessTaskModel.cs

using System.Collections.Generic;
using Windows.System;

namespace TestProject
{
    /// <summary>
    /// 앱 프로세스 태스크 모델
    /// </summary>
    public class AppProcessTaskModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 앱 상세 - AppDetail

        /// <summary>
        /// 앱 상세
        /// </summary>
        public AppDetailModel AppDetail { get; set; }

        #endregion
        #region 프로세스 상세 리스트 - ProcessDetailList

        /// <summary>
        /// 프로세스 상세 리스트
        /// </summary>
        public List<ProcessDetailModel> ProcessDetailList { get; set; }

        #endregion
        #region 앱 리소스 그룹 백그라운드 태스크 리포트 리스트 - AppResourceGroupBackgroundTaskReportList

        /// <summary>
        /// 앱 리소스 그룹 백그라운드 태스크 리포트 리스트
        /// </summary>
        public List<AppResourceGroupBackgroundTaskReport> AppResourceGroupBackgroundTaskReportList { get; set; }

        #endregion
    }
}

 

▶ DynamicSystemModel.cs

namespace TestProject
{
    /// <summary>
    /// 동적 시스템 모델
    /// </summary>
    public class DynamicSystemModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 물리적 메모리 - PhysicalMemory

        /// <summary>
        /// 물리적 메모리
        /// </summary>
        public string PhysicalMemory { get; internal set; }

        #endregion
        #region 물리적 추가 페이지 파일 - PhysicalPlusPageFile

        /// <summary>
        /// 물리적 추가 페이지 파일
        /// </summary>
        public string PhysicalPlusPageFile { get; internal set; }

        #endregion
        #region 가상 메모리 - VirtualMemory

        /// <summary>
        /// 가상 메모리
        /// </summary>
        public string VirtualMemory { get; internal set; }

        #endregion
        #region 디스크상 페이지 파일 - PageFileOnDisk

        /// <summary>
        /// 디스크상 페이지 파일
        /// </summary>
        public string PageFileOnDisk { get; internal set; }

        #endregion
        #region 로드 메모리 - MemoryLoad

        /// <summary>
        /// 로드 메모리
        /// </summary>
        public string MemoryLoad { get; internal set; }

        #endregion
        #region 직렬 라인 상태 - ACLineStatus

        /// <summary>
        /// 직렬 라인 상태
        /// </summary>
        public string ACLineStatus { get; internal set; }

        #endregion
        #region 배터리 충전 상태 - BatteryChargeStatus

        /// <summary>
        /// 배터리 충전 상태
        /// </summary>
        public string BatteryChargeStatus { get; internal set; }

        #endregion
        #region 배터리 수명 - BatteryLife

        /// <summary>
        /// 배터리 수명
        /// </summary>
        public string BatteryLife { get; internal set; }

        #endregion
        #region 배터리 세이버 - BatterySaver

        /// <summary>
        /// 배터리 세이버
        /// </summary>
        public string BatterySaver { get; internal set; }

        #endregion
        #region 충전율 - ChargeRate

        /// <summary>
        /// 충전율
        /// </summary>
        public string ChargeRate { get; internal set; }

        #endregion
        #region 용량 - Capacity

        /// <summary>
        /// 용량
        /// </summary>
        public string Capacity { get; internal set; }

        #endregion
        #region 전체 디스트 크기 - TotalDiskSize

        /// <summary>
        /// 전체 디스트 크기
        /// </summary>
        public string TotalDiskSize { get; internal set; }

        #endregion
        #region 디스크 자유 공간 - DiskFreeSpace

        /// <summary>
        /// 디스크 자유 공간
        /// </summary>
        public string DiskFreeSpace { get; internal set; }

        #endregion
        #region 도메인명 - DomainName

        /// <summary>
        /// 도메인명
        /// </summary>
        public string DomainName { get; internal set; }

        #endregion
        #region 노드 타입 - NodeType

        /// <summary>
        /// 노드 타입
        /// </summary>
        public string NodeType { get; internal set; }

        #endregion
        #region 연결된 프로필 - ConnectedProfile

        /// <summary>
        /// 연결된 프로필
        /// </summary>
        public string ConnectedProfile { get; internal set; }

        #endregion
        #region IANA 인터페이스 타입 - IANAInterfaceType

        /// <summary>
        /// IANA 인터페이스 타입
        /// </summary>
        public string IANAInterfaceType { get; internal set; }

        #endregion
        #region 인바운드 속도 - InboundSpeed

        /// <summary>
        /// 인바운드 속도
        /// </summary>
        public string InboundSpeed { get; internal set; }

        #endregion
        #region 아웃바운드 속도 - OutboundSpeed

        /// <summary>
        /// 아웃바운드 속도
        /// </summary>
        public string OutboundSpeed { get; internal set; }

        #endregion
        #region 호스트 주소 - HostAddress

        /// <summary>
        /// 호스트 주소
        /// </summary>
        public string HostAddress { get; internal set; }

        #endregion
        #region 주소 타입 - AddressType

        /// <summary>
        /// 주소 타입
        /// </summary>
        public string AddressType { get; internal set; }

        #endregion
    }
}

 

▶ GroupDetailModel.cs

using System;
using System.Collections.Generic;
using Windows.System;

namespace TestProject
{
    /// <summary>
    /// 그룹 상세 모델
    /// </summary>
    public class GroupDetailModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 인스턴스 ID - InstanceID

        /// <summary>
        /// 인스턴스 ID
        /// </summary>
        public Guid InstanceID { get; internal set; }

        #endregion
        #region 공유 여부 - IsShared

        /// <summary>
        /// 공유 여부
        /// </summary>
        public bool IsShared { get; internal set; }

        #endregion
        #region 커밋 사용 레벨 - CommitUsageLevel

        /// <summary>
        /// 커밋 사용 레벨
        /// </summary>
        public AppMemoryUsageLevel CommitUsageLevel { get; internal set; }

        #endregion
        #region 커밋 사용 제한 - CommitUsageLimit

        /// <summary>
        /// 커밋 사용 제한
        /// </summary>
        public ulong CommitUsageLimit { get; internal set; }

        #endregion
        #region 개인 커밋 사용 - PrivateCommitUsage

        /// <summary>
        /// 개인 커밋 사용
        /// </summary>
        public ulong PrivateCommitUsage { get; internal set; }

        #endregion
        #region 전체 커밋 사용 - TotalCommitUsage

        /// <summary>
        /// 전체 커밋 사용
        /// </summary>
        public ulong TotalCommitUsage { get; internal set; }

        #endregion
        #region 실행 상태 - ExecutionState

        /// <summary>
        /// 실행 상태
        /// </summary>
        public AppResourceGroupExecutionState ExecutionState { get; internal set; }

        #endregion
        #region 에너지 할당 상태 - EnergyQuotaState

        /// <summary>
        /// 에너지 할당 상태
        /// </summary>
        public AppResourceGroupEnergyQuotaState EnergyQuotaState { get; internal set; }

        #endregion
        #region 앱 리소스 그룹 백그라운드 태스크 리포트 리스트 - AppResourceGroupBackgroundTaskReportList

        /// <summary>
        /// 앱 리소스 그룹 백그라운드 태스크 리포트 리스트
        /// </summary>
        public IList<AppResourceGroupBackgroundTaskReport> AppResourceGroupBackgroundTaskReportList { get; internal set; }

        #endregion
        #region 프로세스 상세 리스트 - ProcessDetailList

        /// <summary>
        /// 프로세스 상세 리스트
        /// </summary>
        public IList<ProcessDetailModel> ProcessDetailList { get; internal set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - GroupDetailModel(instanceID, isShared, commitUsageLevel, commitUsageLimit, privateCommitUsage,
            totalCommitUsage, executionState, energyQuotaState, appResourceGroupBackgroundTaskReportList, processDetailList)

        /// <summary>
        /// 
        /// </summary>
        /// <param name="instanceID">인스턴스 ID</param>
        /// <param name="isShared">공유 여부</param>
        /// <param name="commitUsageLevel">커밋 사용 레벨</param>
        /// <param name="commitUsageLimit">커밋 사용 제한</param>
        /// <param name="privateCommitUsage">개인 커밋 사용</param>
        /// <param name="totalCommitUsage">전체 커밋 사용</param>
        /// <param name="executionState">실행 상태</param>
        /// <param name="energyQuotaState">에너지 할당 상태</param>
        /// <param name="appResourceGroupBackgroundTaskReportList">앱 리소스 그룹 백그라운드 태스크 리포트 리스트</param>
        /// <param name="processDetailList">프로세스 상세 리스트</param>
        public GroupDetailModel
        (
            Guid                                        instanceID,
            bool                                        isShared,
            AppMemoryUsageLevel                         commitUsageLevel,
            ulong                                       commitUsageLimit,
            ulong                                       privateCommitUsage,
            ulong                                       totalCommitUsage,
            AppResourceGroupExecutionState              executionState,
            AppResourceGroupEnergyQuotaState            energyQuotaState,
            IList<AppResourceGroupBackgroundTaskReport> appResourceGroupBackgroundTaskReportList,
            IList<ProcessDetailModel>                   processDetailList
        )
        {
            InstanceID                               = instanceID;
            IsShared                                 = isShared;
            CommitUsageLevel                         = commitUsageLevel;
            CommitUsageLimit                         = commitUsageLimit;
            PrivateCommitUsage                       = privateCommitUsage;
            TotalCommitUsage                         = totalCommitUsage;
            ExecutionState                           = executionState;
            EnergyQuotaState                         = energyQuotaState;
            AppResourceGroupBackgroundTaskReportList = appResourceGroupBackgroundTaskReportList;
            ProcessDetailList                        = processDetailList;
        }

        #endregion
    }
}

 

▶ ProcessCollection.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.System.Diagnostics;
using Windows.UI.Xaml.Media.Imaging;

namespace TestProject
{
    /// <summary>
    /// 프로세스 컬렉션
    /// </summary>
    public class ProcessCollection : ObservableCollection<ProcessModel>
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 디폴트 프로세스 이미지
        /// </summary>
        private BitmapImage defaultProcessImage;

        /// <summary>
        /// 디폴트 앱 이미지
        /// </summary>
        private BitmapImage defaultAppImage;

        /// <summary>
        /// 정렬 순서 딕셔너리
        /// </summary>
        private Dictionary<string, bool> sortOrderDictionary = new Dictionary<string, bool>();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ProcessCollection()

        /// <summary>
        /// 생성자
        /// </summary>
        public ProcessCollection()
        {
            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.sortOrderDictionary.Add("ExecutableFileName", true );
            this.sortOrderDictionary.Add("ProcessID"         , false);
            this.sortOrderDictionary.Add("KernelTime"        , false);
            this.sortOrderDictionary.Add("UserTime"          , false);
            this.sortOrderDictionary.Add("PageFileSize"      , false);
            this.sortOrderDictionary.Add("WorkingSetSize"    , false);
            this.sortOrderDictionary.Add("ReadByteCount"     , false);
            this.sortOrderDictionary.Add("WriteByteCount"    , false);
            this.sortOrderDictionary.Add("AppType"           , false);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 업데이트하기 - Update()

        /// <summary>
        /// 업데이트하기
        /// </summary>
        public void Update()
        {
            Clear();

            IReadOnlyList<ProcessDiagnosticInfo> processDiagnosticInfoList = ProcessDiagnosticInfo.GetForProcesses();

            if(processDiagnosticInfoList != null)
            {
                foreach(ProcessDiagnosticInfo processDiagnosticInfo in processDiagnosticInfoList)
                {
                    BitmapImage bitmapImage = null;

                    if(processDiagnosticInfo.IsPackaged)
                    {
                        bitmapImage = this.defaultAppImage;
                    }
                    else
                    {
                        bitmapImage = this.defaultProcessImage;
                    }

                    ProcessModel process = new ProcessModel(processDiagnosticInfo, bitmapImage);

                    Add(process);
                }
            }
        }

        #endregion
        #region 정렬하기 - Sort(column, isUserAction)

        /// <summary>
        /// 정렬하기
        /// </summary>
        /// <param name="column">컬럼</param>
        /// <param name="isUserAction">사용자 액션 여부</param>
        public void Sort(string column, bool isUserAction)
        {
            List<ProcessModel> processList = null;

            switch(column)
            {
                case "ExecutableFileName" : processList = this.OrderBy(a => a.ExecutableFileName).ToList(); break;
                case "ProcessID"          : processList = this.OrderBy(a => a.ProcessID         ).ToList(); break;
                case "KernelTime"         : processList = this.OrderBy(a => a.KernelTime        ).ToList(); break;
                case "UserTime"           : processList = this.OrderBy(a => a.UserTime          ).ToList(); break;
                case "PageFileSize"       : processList = this.OrderBy(a => a.PageFileSize      ).ToList(); break;
                case "WorkingSetSize"     : processList = this.OrderBy(a => a.WorkingSetSize    ).ToList(); break;
                case "ReadByteCount"      : processList = this.OrderBy(a => a.ReadByteCount     ).ToList(); break;
                case "WriteByteCount"     : processList = this.OrderBy(a => a.WriteByteCount    ).ToList(); break;
                case "AppType"            : processList = this.OrderBy(a => a.AppType           ).ToList(); break;
            }

            KeyValuePair<string, bool> keyValuePair = this.sortOrderDictionary.FirstOrDefault(i => i.Key == column);

            bool isAscending = keyValuePair.Value;

            if(isUserAction)
            {
                isAscending = !isAscending;

                this.sortOrderDictionary[column] = isAscending;
            }

            if(isAscending == false)
            {
                processList.Reverse();
            }

            for(int i = 0; i < processList.Count(); i++)
            {
                Move(IndexOf(processList[i]), i);
            }
        }

        #endregion
    }
}

 

▶ ProcessDetailModel.cs

using System;

namespace TestProject
{
    /// <summary>
    /// 프로세스 상세 모델
    /// </summary>
    public class ProcessDetailModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 프로세스 ID - ProcessID

        /// <summary>
        /// 프로세스 ID
        /// </summary>
        public int ProcessID { get; internal set; }

        #endregion
        #region 실행 파일명 - ExecutableFileName

        /// <summary>
        /// 실행 파일명
        /// </summary>
        public string ExecutableFileName { get; internal set; }

        #endregion

        #region 프로세스 시작 시간 - ProcessStartTime

        /// <summary>
        /// 프로세스 시작 시간
        /// </summary>
        public DateTimeOffset ProcessStartTime { get; internal set; }

        #endregion
        #region 커널 시간 - KernelTime

        /// <summary>
        /// 커널 시간
        /// </summary>
        public TimeSpan KernelTime { get; internal set; }

        #endregion
        #region 사용자 시간 - UserTime

        /// <summary>
        /// 사용자 시간
        /// </summary>
        public TimeSpan UserTime { get; internal set; }

        #endregion

        #region 비 페이지 풀 크기 (바이트) - NonPagedPoolSize

        /// <summary>
        /// 비 페이지 풀 크기 (바이트)
        /// </summary>
        public ulong NonPagedPoolSize { get; internal set; }

        #endregion
        #region 페이지 풀 크기 (바이트) - PagedPoolSize

        /// <summary>
        /// 페이지 풀 크기 (바이트)
        /// </summary>
        public ulong PagedPoolSize { get; internal set; }

        #endregion
        #region 페이지 폴트 카운트 - PageFaultCount

        /// <summary>
        /// 페이지 폴트 카운트
        /// </summary>
        public ulong PageFaultCount { get; internal set; }

        #endregion
        #region 페이지 파일 크기 (바이트) - PageFileSize

        /// <summary>
        /// 페이지 파일 크기 (바이트)
        /// </summary>
        public ulong PageFileSize { get; internal set; }

        #endregion
        #region 피크 비 페이지 풀 크기 (바이트) - PeakNonPagedPoolSize

        /// <summary>
        /// 피크 비 페이지 풀 크기 (바이트)
        /// </summary>
        public ulong PeakNonPagedPoolSize { get; internal set; }

        #endregion
        #region 피크 페이지 풀 크기 (바이트) - PeakPagedPoolSize

        /// <summary>
        /// 피크 페이지 풀 크기 (바이트)
        /// </summary>
        public ulong PeakPagedPoolSize { get; internal set; }

        #endregion
        #region 피크 페이지 파일 크기 (바이트) - PeakPageFileSize

        /// <summary>
        /// 피크 페이지 파일 크기 (바이트)
        /// </summary>
        public ulong PeakPageFileSize { get; internal set; }

        #endregion
        #region 피크 가상 메모리 크기 (바이트) - PeakVirtualMemorySize

        /// <summary>
        /// 피크 가상 메모리 크기 (바이트)
        /// </summary>
        public ulong PeakVirtualMemorySize { get; internal set; }

        #endregion
        #region 피크 작업 세트 크기 (바이트) - PeakWorkingSetSize

        /// <summary>
        /// 피크 작업 세트 크기 (바이트)
        /// </summary>
        public ulong PeakWorkingSetSize { get; internal set; }

        #endregion
        #region 개인 페이지 카운트 - PrivatePageCount

        /// <summary>
        /// 개인 페이지 카운트
        /// </summary>
        public ulong PrivatePageCount { get; internal set; }

        #endregion
        #region 가상 메모리 크기 (바이트) - VirtualMemorySize

        /// <summary>
        /// 가상 메모리 크기 (바이트)
        /// </summary>
        public ulong VirtualMemorySize { get; internal set; }

        #endregion
        #region 작업 세트 크기 (바이트) - WorkingSetSize

        /// <summary>
        /// 작업 세트 크기 (바이트)
        /// </summary>
        public ulong WorkingSetSize { get; internal set; }

        #endregion

        #region 읽기 바이트 카운트 - ReadByteCount

        /// <summary>
        /// 읽기 바이트 카운트
        /// </summary>
        public long ReadByteCount { get; internal set; }

        #endregion
        #region 쓰기 바이트 카운트 - WriteByteCount

        /// <summary>
        /// 쓰기 바이트 카운트
        /// </summary>
        public long WriteByteCount { get; internal set; }

        #endregion
        #region 기타 바이트 카운트 - OtherByteCount

        /// <summary>
        /// 기타 바이트 카운트
        /// </summary>
        public long OtherByteCount { get; internal set; }

        #endregion
        #region 기타 작업 카운트 - OtherOperationCount

        /// <summary>
        /// 기타 작업 카운트
        /// </summary>
        public long OtherOperationCount { get; internal set; }

        #endregion
        #region 읽기 작업 카운트 - ReadOperationCount

        /// <summary>
        /// 읽기 작업 카운트
        /// </summary>
        public long ReadOperationCount { get; internal set; }

        #endregion
        #region 쓰기 작업 카운트 - WriteOperationCount

        /// <summary>
        /// 쓰기 작업 카운트
        /// </summary>
        public long WriteOperationCount { get; internal set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ProcessDetailModel(processID, executableFileName, processStartTime, kernelTime, userTime, nonPagedPoolSize,
            pagedPoolSize, pageFaultCount, pageFileSize, peakNonPagedPoolSize, peakPagedPoolSize, peakPageFileSize, peakVirtualMemorySize,
            peakWorkingSetSize, privatePageCount, virtualMemorySize, workingSetSize, readByteCount, writeByteCount, otherByteCount,
            otherOperationCount, readOperationCount, writeOperationCount)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="processID">프로세스 ID</param>
        /// <param name="executableFileName">실행 파일명</param>
        /// <param name="processStartTime">프로세스 시작 시간</param>
        /// <param name="kernelTime">커널 시간</param>
        /// <param name="userTime">사용자 시간</param>
        /// <param name="nonPagedPoolSize">비 페이지 풀 크기 (바이트)</param>
        /// <param name="pagedPoolSize">페이지 풀 크기 (바이트)</param>
        /// <param name="pageFaultCount">페이지 폴트 카운트</param>
        /// <param name="pageFileSize">페이지 파일 크기 (바이트)</param>
        /// <param name="peakNonPagedPoolSize">피크 비 페이지 풀 크기 (바이트)</param>
        /// <param name="peakPagedPoolSize">피크 페이지 풀 크기 (바이트)</param>
        /// <param name="peakPageFileSize">피크 페이지 파일 크기 (바이트)</param>
        /// <param name="peakVirtualMemorySize">피크 가상 메모리 크기 (바이트)</param>
        /// <param name="peakWorkingSetSize">피크 작업 세트 크기 (바이트)</param>
        /// <param name="privatePageCount">개인 페이지 카운트</param>
        /// <param name="virtualMemorySize">가상 메모리 크기 (바이트)</param>
        /// <param name="workingSetSize">작업 세트 크기 (바이트)</param>
        /// <param name="readByteCount">읽기 바이트 카운트</param>
        /// <param name="writeByteCount">쓰기 바이트 카운트</param>
        /// <param name="otherByteCount">기타 바이트 카운트</param>
        /// <param name="otherOperationCount">기타 작업 카운트</param>
        /// <param name="readOperationCount">읽기 작업 카운트</param>
        /// <param name="writeOperationCount">쓰기 작업 카운트</param>
        public ProcessDetailModel
        (
            uint           processID,
            string         executableFileName,
            DateTimeOffset processStartTime,
            TimeSpan       kernelTime,
            TimeSpan       userTime,
            ulong          nonPagedPoolSize,
            ulong          pagedPoolSize,
            ulong          pageFaultCount,
            ulong          pageFileSize,
            ulong          peakNonPagedPoolSize,
            ulong          peakPagedPoolSize,
            ulong          peakPageFileSize,
            ulong          peakVirtualMemorySize,
            ulong          peakWorkingSetSize,
            ulong          privatePageCount,
            ulong          virtualMemorySize,
            ulong          workingSetSize,
            long           readByteCount,
            long           writeByteCount,
            long           otherByteCount,
            long           otherOperationCount,
            long           readOperationCount,
            long           writeOperationCount
        )
        {
            ProcessID          = (int)processID;
            ExecutableFileName = executableFileName;
            ProcessStartTime   = processStartTime;

            KernelTime = kernelTime;
            UserTime   = userTime;

            NonPagedPoolSize      = nonPagedPoolSize;
            PagedPoolSize         = pagedPoolSize;
            PageFaultCount        = pageFaultCount;
            PageFileSize          = pageFileSize;
            PeakNonPagedPoolSize  = peakNonPagedPoolSize;
            PeakPagedPoolSize     = peakPagedPoolSize;
            PeakPageFileSize      = peakPageFileSize;
            PeakVirtualMemorySize = peakVirtualMemorySize;
            PeakWorkingSetSize    = peakWorkingSetSize;
            PrivatePageCount      = privatePageCount;
            VirtualMemorySize     = virtualMemorySize;
            WorkingSetSize        = workingSetSize;

            ReadByteCount       = readByteCount;
            WriteByteCount      = writeByteCount;
            OtherByteCount      = otherByteCount;
            OtherOperationCount = otherOperationCount;
            ReadOperationCount  = readOperationCount;
            WriteOperationCount = writeOperationCount;
        }

        #endregion
    }
}

 

▶ ProcessModel.cs

using System;
using Windows.System.Diagnostics;
using Windows.UI.Xaml.Media.Imaging;

namespace TestProject
{
    /// <summary>
    /// 프로세스 모델
    /// </summary>
    public class ProcessModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 프로세스 진단 정보
        /// </summary>
        private ProcessDiagnosticInfo processDiagnosticInfo;

        /// <summary>
        /// 프로세스 CPU 사용 리포트
        /// </summary>
        private ProcessCpuUsageReport processCpuUsageReport;

        /// <summary>
        /// 프로세스 메모리 사용 리포트
        /// </summary>
        private ProcessMemoryUsageReport processMemoryUsageReport;

        /// <summary>
        /// 프로세스 디스크 사용 리포트
        /// </summary>
        private ProcessDiskUsageReport processDiskUsageReport;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 실행 파일명 - ExecutableFileName

        /// <summary>
        /// 실행 파일명
        /// </summary>
        public string ExecutableFileName
        {
            get
            {
                return this.processDiagnosticInfo.ExecutableFileName;
            }
        }

        #endregion
        #region 프로세스 ID - ProcessID

        /// <summary>
        /// 프로세스 ID
        /// </summary>
        public uint ProcessID
        {
            get
            {
                return this.processDiagnosticInfo.ProcessId;
            }
        }

        #endregion
        #region 프로세스 시작 시간 - ProcessStartTime

        /// <summary>
        /// 프로세스 시작 시간
        /// </summary>
        public DateTimeOffset ProcessStartTime
        {
            get
            {
                return this.processDiagnosticInfo.ProcessStartTime;
            }
        }

        #endregion

        #region 커널 시간 - KernelTime

        /// <summary>
        /// 커널 시간
        /// </summary>
        public TimeSpan KernelTime
        {
            get
            {
                return this.processCpuUsageReport != null ? this.processCpuUsageReport.KernelTime : TimeSpan.MinValue;
            }
        }

        #endregion
        #region 사용자 시간 - UserTime

        /// <summary>
        /// 사용자 시간
        /// </summary>
        public TimeSpan UserTime
        {
            get
            {
                return this.processCpuUsageReport != null ? this.processCpuUsageReport.UserTime : TimeSpan.MinValue;
            }
        }

        #endregion
        #region CPU 시간 - CPUTime

        /// <summary>
        /// CPU 시간
        /// </summary>
        public TimeSpan CPUTime
        {
            get
            {
                return this.processCpuUsageReport != null ? this.processCpuUsageReport.KernelTime + this.processCpuUsageReport.UserTime : TimeSpan.MinValue;
            }
        }

        #endregion

        #region 페이지 파일 크기 (바이트) - PageFileSize

        /// <summary>
        /// 페이지 파일 크기 (바이트)
        /// </summary>
        public ulong PageFileSize
        {
            get
            {
                return this.processMemoryUsageReport != null ? this.processMemoryUsageReport.PageFileSizeInBytes : ulong.MinValue;
            }
        }

        #endregion
        #region 작업 세트 크기 (바이트) - WorkingSetSize

        /// <summary>
        /// 작업 세트 크기 (바이트)
        /// </summary>
        public ulong WorkingSetSize
        {
            get
            {
                return this.processMemoryUsageReport != null ? this.processMemoryUsageReport.WorkingSetSizeInBytes : ulong.MinValue;
            }
        }

        #endregion

        #region 읽기 바이트 카운트 - ReadByteCount

        /// <summary>
        /// 읽기 바이트 카운트
        /// </summary>
        public ulong ReadByteCount
        {
            get
            {
                return this.processDiskUsageReport != null ? (ulong)this.processDiskUsageReport.BytesReadCount : ulong.MinValue;
            }
        }

        #endregion
        #region 쓰기 바이트 카운트 - WriteByteCount

        /// <summary>
        /// 쓰기 바이트 카운트
        /// </summary>
        public ulong WriteByteCount
        {
            get
            {
                return this.processDiskUsageReport != null ? (ulong)this.processDiskUsageReport.BytesWrittenCount : ulong.MinValue;
            }
        }

        #endregion
        #region 디스크 바이트 카운트 - DiskByteCount

        /// <summary>
        /// 디스크 바이트 카운트
        /// </summary>
        public ulong DiskByteCount
        {
            get
            {
                return this.processDiskUsageReport != null ?
                    (ulong)(this.processDiskUsageReport.BytesReadCount + this.processDiskUsageReport.BytesWrittenCount) :
                    ulong.MinValue;
            }
        }

        #endregion

        #region 로고 - Logo

        /// <summary>
        /// 로고
        /// </summary>
        public BitmapImage Logo { get; set; }

        #endregion
        #region 앱 타입 - AppType

        /// <summary>
        /// 앱 타입
        /// </summary>
        public string AppType { get; set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ProcessModel(processDiagnosticInfo, bitmapImage)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="processDiagnosticInfo">프로세스 진단 정보</param>
        /// <param name="bitmapImage">비트맵 이미지</param>
        public ProcessModel(ProcessDiagnosticInfo processDiagnosticInfo, BitmapImage bitmapImage)
        {
            this.processDiagnosticInfo = processDiagnosticInfo;

            this.processCpuUsageReport    = this.processDiagnosticInfo.CpuUsage.GetReport();
            this.processDiskUsageReport   = this.processDiagnosticInfo.DiskUsage.GetReport();
            this.processMemoryUsageReport = this.processDiagnosticInfo.MemoryUsage.GetReport();

            Logo    = bitmapImage;
            AppType = processDiagnosticInfo.IsPackaged ? "Packaged" : "Win32";
        }

        #endregion
    }
}

 

▶ StaticSystemModel.cs

namespace TestProject
{
    /// <summary>
    /// 정적 시스템 모델
    /// </summary>
    public class StaticSystemModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 장치명 - MachineName

        /// <summary>
        /// 장치명
        /// </summary>
        public string MachineName { get; internal set; }

        #endregion
        #region 제조 모델 - MakeModel

        /// <summary>
        /// 제조 모델
        /// </summary>
        public string MakeModel { get; internal set; }

        #endregion
        #region 폼 팩터 - FormFactor

        /// <summary>
        /// 폼 팩터
        /// </summary>
        public string FormFactor { get; internal set; }

        #endregion
        #region OS 버전 - OSVersion

        /// <summary>
        /// OS 버전
        /// </summary>
        public string OSVersion { get; internal set; }

        #endregion
        #region 논리적 프로세서 카운트 - LogicalProcessorCount

        /// <summary>
        /// 논리적 프로세서 카운트
        /// </summary>
        public string LogicalProcessorCount { get; internal set; }

        #endregion
        #region 프로세서 - Processor

        /// <summary>
        /// 프로세서
        /// </summary>
        public string Processor { get; internal set; }

        #endregion
        #region 페이지 크기 - PageSize

        /// <summary>
        /// 페이지 크기
        /// </summary>
        public string PageSize { get; internal set; }

        #endregion
    }
}

 

▶ CACHE_DESCRIPTOR.cs

using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// 캐시 설명자
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct CACHE_DESCRIPTOR
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 레벨
        /// </summary>
        public byte Level;

        /// <summary>
        /// 결합도
        /// </summary>
        public byte Associativity;

        /// <summary>
        /// 라인 크기
        /// </summary>
        public ushort LineSize;

        /// <summary>
        /// 크기
        /// </summary>
        public uint Size;

        /// <summary>
        /// 프로세서 캐시 타입
        /// </summary>
        public PROCESSOR_CACHE_TYPE Type;

        #endregion
    }
}

 

▶ FIXED_INFORMATION.cs

using System;
using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// 고정 정보
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct FIXED_INFORMATION
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 호스트명
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WIN32Helper.MAXIMUM_HOSTNAME_LENGTH + 4)]
        public string HostName;

        /// <summary>
        /// 도메인명
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WIN32Helper.MAXIMUM_HOSTNAME_LENGTH + 4)]
        public string DomainName;

        /// <summary>
        /// 현재 DNS 서버 핸들
        /// </summary>
        public IntPtr CurrentDNSServerHandle;

        /// <summary>
        /// DNS 서버 리스트
        /// </summary>
        public IP_ADDRESS_STRING DNSServerList;

        /// <summary>
        /// 노드 타입
        /// </summary>
        public uint NodeType;

        /// <summary>
        /// 범위 ID
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WIN32Helper.MAXIMUM_SCOPE_ID_LENGTH + 4)]
        public string ScopeID;

        /// <summary>
        /// 라우팅 이용 가능 여부
        /// </summary>
        public uint EnableRouting;

        /// <summary>
        /// 프록시 이용 가능 여부
        /// </summary>
        public uint EnableProxy;

        /// <summary>
        /// DNS 이용 가능 여부
        /// </summary>
        public uint EnableDNS;

        #endregion
    }
}

 

▶ IP_ADDRESS_STRING.cs

using System;
using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// IP 주소 문자열
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct IP_ADDRESS_STRING
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 다음 핸들
        /// </summary>
        public IntPtr NextHandle;

        /// <summary>
        /// IP 주소
        /// </summary>
        public IP_ADDRESS_STRING_CORE IPAddress;

        /// <summary>
        /// IP 마스크
        /// </summary>
        public IP_ADDRESS_STRING_CORE IPMask;

        /// <summary>
        /// 컨텍스트
        /// </summary>
        public int Context;

        #endregion
    }
}

 

▶ IP_ADDRESS_STRING_CORE.cs

using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// IP 주소 문자열 (코어)
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct IP_ADDRESS_STRING_CORE
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 주소
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string Address;

        #endregion
    }
}

 

▶ MEMORYSTATUSEX.cs

using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// 메모리 상태 (확장)
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public class MEMORYSTATUSEX
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 길이
        /// </summary>
        public uint Length;

        /// <summary>
        /// 로드 메모리
        /// </summary>
        public uint MemoryLoad;

        /// <summary>
        /// 전체 물리적 메모리 크기
        /// </summary>
        public ulong TotalPhysicalMemorySize;

        /// <summary>
        /// 이용 가능한 물리적 메모리 크기
        /// </summary>
        public ulong AvailablePhysicalMemorySize;

        /// <summary>
        /// 전체 페이지 파일 크기
        /// </summary>
        public ulong TotalPageFileSize;

        /// <summary>
        /// 이용 가능한 페이지 파일 크기
        /// </summary>
        public ulong AvailablePageFileSize;

        /// <summary>
        /// 전체 가상 메모리 크기
        /// </summary>
        public ulong TotalVirtualMemorySize;

        /// <summary>
        /// 이용 가능한 가상 메모리 크기
        /// </summary>
        public ulong AvailableVirtualMemorySize;

        /// <summary>
        /// 이용 가능한 확장된 가상 메모리 크기
        /// </summary>
        public ulong AvailableExtendedVirtualMemorySize;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MEMORYSTATUSEX()

        /// <summary>
        /// 생성자
        /// </summary>
        public MEMORYSTATUSEX()
        {
            Length = (uint)Marshal.SizeOf<MEMORYSTATUSEX>();
        }

        #endregion
    }
}

 

▶ NUMANODE.cs

using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// NUMA 노드
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct NUMANODE
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 노드 번호
        /// </summary>
        public uint NodeNumber;

        #endregion
    }
}

 

▶ PROCESSORCORE.cs

using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// 프로세서 코어
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct PROCESSORCORE
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 플래그
        /// </summary>
        public byte Flag;

        #endregion
    };
}

 

▶ SYSTEM_INFORMATION.cs

using System;
using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// 시스템 정보
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct SYSTEM_INFORMATION
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 프로세서 아키텍처
        /// </summary>
        public ProcessorArchitecture ProcessorArchitecture;

        /// <summary>
        /// 예약
        /// </summary>
        public ushort Reserved;

        /// <summary>
        /// 페이지 크기
        /// </summary>
        public uint PageSize;

        /// <summary>
        /// 최소 애플리케이션 주소
        /// </summary>
        public IntPtr MinimumApplicationAddress;

        /// <summary>
        /// 최대 애플리케이션 주소
        /// </summary>
        public IntPtr MaximumApplicationAddress;

        /// <summary>
        /// 활성 프로세서 마스크
        /// </summary>
        public UIntPtr ActiveProcessorMask;

        /// <summary>
        /// 프로세서 카운트
        /// </summary>
        public uint ProcessorCount;

        /// <summary>
        /// 프로세서 타입
        /// </summary>
        public uint ProcessorType;

        /// <summary>
        /// 할당 입도
        /// </summary>
        public uint AllocationGranularity;

        /// <summary>
        /// 프로세서 레벨
        /// </summary>
        public ushort ProcessorLevel;

        /// <summary>
        /// 프로세서 수정
        /// </summary>
        public ushort ProcessorRevision;

        #endregion
    };
}

 

▶ SYSTEM_LOGICAL_PROCESSOR_INFORMATION.cs

using System;

namespace TestProject
{
    /// <summary>
    /// 시스템 논리적 프로세서 정보
    /// </summary>
    public struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 프로세서 마스크
        /// </summary>
        public UIntPtr ProcessorMask;

        /// <summary>
        /// 관계
        /// </summary>
        public LOGICAL_PROCESSOR_RELATIONSHIP Relationship;

        /// <summary>
        /// 프로세서 정보
        /// </summary>
        public SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION ProcessorInformation;

        #endregion
    }
}

 

▶ SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION.cs

using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// 시스템 논리적 프로세서 정보 공용
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 프로세서 코어
        /// </summary>
        [FieldOffset(0)]
        public PROCESSORCORE ProcessorCore;

        /// <summary>
        /// NUMA 노드
        /// </summary>
        [FieldOffset(0)]
        public NUMANODE NumaNode;

        /// <summary>
        /// 캐시 설명자
        /// </summary>
        [FieldOffset(0)]
        public CACHE_DESCRIPTOR CacheDescriptor;

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 예약 1
        /// </summary>
        [FieldOffset(0)]
        private ulong Reserved1;

        /// <summary>
        /// 예약 2
        /// </summary>
        [FieldOffset(8)]
        private ulong Reserved2;

        #endregion
    }
}

 

▶ SYSTEM_POWER_STATUS.cs

using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// 시스템 전원 상태
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct SYSTEM_POWER_STATUS
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 직렬 라인 상태
        /// </summary>
        public ACLineStatus ACLineStatus;

        /// <summary>
        /// 배터리 충전 상태
        /// </summary>
        public BatteryFlag BatteryChargeStatus;

        /// <summary>
        /// 배터리 수명 (비율)
        /// </summary>
        public byte BatteryLifePercent;

        /// <summary>
        /// 배터리 세이버
        /// </summary>
        public SystemStatusFlag BatterySaver;

        /// <summary>
        /// 배터리 수명 시간 (초)
        /// </summary>
        public int BatteryLifeTime;

        /// <summary>
        /// 전체 배터리 수명 시간 (초)
        /// </summary>
        public int FullBatteryLifeTime;

        #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"
    RequestedTheme="Light">
</Application>

 

▶ App.xaml.cs

using System.Diagnostics;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Graphics.Display;
using Windows.System.Display;
using Windows.System.Profile;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace TestProject
{
    /// <summary>
    /// 앱
    /// </summary>
    sealed partial class App : Application
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 디스플레이 요청
        /// </summary>
        private static DisplayRequest _displayRequest;

        /// <summary>
        /// 디스플레이 요청 활성화 여부
        /// </summary>
        private static bool _isDisplayRequestActive = false;

        /// <summary>
        /// 버전 문자열
        /// </summary>
        private static string _versionString = string.Empty;

        /// <summary>
        /// 장치 폼 팩터 타입
        /// </summary>
        private static DeviceFormFactorType _deviceFormFactorType = DeviceFormFactorType.Unknown;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 버전 문자열 - VersionString

        /// <summary>
        /// 버전 문자열
        /// </summary>
        public static string VersionString
        {
            get
            {
                if(string.IsNullOrEmpty(_versionString))
                {
                    PackageVersion packageVersion = Package.Current.Id.Version;

                    _versionString = $"{packageVersion.Major}.{packageVersion.Minor}.{packageVersion.Build}.{packageVersion.Revision}";
                }

                return _versionString;
            }
        }

        #endregion
        #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;
                    }

                    WriteLog("App.DeviceFormFactorType", AnalyticsInfo.VersionInfo.DeviceFamily.ToString(), _deviceFormFactorType.ToString());
                }

                return _deviceFormFactorType;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - App()

        /// <summary>
        /// 생성자
        /// </summary>
        public App()
        {
            UnhandledException += App_UnhandledException;

            InitializeComponent();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 로그 쓰기 - WriteLog(eventName, header, payload)

        /// <summary>
        /// 로그 쓰기
        /// </summary>
        /// <param name="eventName">이벤트명</param>
        /// <param name="header">헤더</param>
        /// <param name="payload">페이로드</param>
        public static void WriteLog(string eventName, string header, string payload)
        {
            Debug.WriteLine($"{eventName} | {header} | {payload}");
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Internal

        #region 디스플레이 요청 활성화하기 - ActivateDisplayRequest()

        /// <summary>
        /// 디스플레이 요청 활성화하기
        /// </summary>
        internal static void ActivateDisplayRequest()
        {
            if(!_isDisplayRequestActive)
            {
                if(_displayRequest == null)
                {
                    _displayRequest = new DisplayRequest();
                }

                _displayRequest.RequestActive();

                _isDisplayRequestActive = true;
            }
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Protected

        #region 시작시 처리하기 - OnLaunched(e)

        /// <summary>
        /// 시작시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
            WriteLog("App.OnLaunched", "LaunchActivatedEventArgs", e.Kind.ToString());

            Frame rootFrame = Window.Current.Content as Frame;

            if(rootFrame == null)
            {
                rootFrame = new Frame();

                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
        ////////////////////////////////////////////////////////////////////// Event

        #region 앱 미처리 예외 처리하기 - App_UnhandledException(sender, e)

        /// <summary>
        /// 앱 미처리 예외 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            WriteLog("App.UnhandledException", "Exception", e.ToString());
        }

        #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:local="using:TestProject"
    SizeChanged="Page_SizeChanged">
    <Page.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="FontSize"            Value="12"     />
            <Setter Property="HorizontalAlignment" Value="Left"   />
            <Setter Property="VerticalAlignment"   Value="Center" />
            <Setter Property="TextWrapping"        Value="Wrap"   />
        </Style>
        <local:ByteToMegabyteConverter x:Key="ByteToMegabyteConverterKey" />
        <local:MemoryLimitConverter x:Key="MemoryLimitConverterKey" />
        <local:CPUTimeConverter x:Key="CPUTimeConverterKey" />
        <local:NegativeValueConverter x:Key="NegativeValueConverterKey" />
        <local:EnergyQuotaStateConverter x:Key="EnergyQuotaStateConverterKey" />
        <local:StringFormatConverter x:Key="StringFormatConverterKey" />
        <Style TargetType="PivotHeaderItem">
            <Setter Property="Height"                   Value="68"                                                  />
            <Setter Property="Padding"                  Value="{ThemeResource PivotHeaderItemMargin}"               />
            <Setter Property="Background"               Value="{ThemeResource PivotHeaderItemBackgroundUnselected}" />
            <Setter Property="Foreground"               Value="{ThemeResource PivotHeaderItemForegroundUnselected}" />
            <Setter Property="CharacterSpacing"         Value="{ThemeResource PivotHeaderItemCharacterSpacing}"     />
            <Setter Property="FontFamily"               Value="{ThemeResource PivotHeaderItemFontFamily}"           />
            <Setter Property="FontSize"                 Value="{ThemeResource PivotHeaderItemFontSize}"             />
            <Setter Property="FontWeight"               Value="{ThemeResource PivotHeaderItemThemeFontWeight}"      />
            <Setter Property="IsTabStop"                Value="False"                                               />
            <Setter Property="VerticalContentAlignment" Value="Center"                                              />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="PivotHeaderItem">
                        <Grid Name="Grid"
                            Padding="{TemplateBinding Padding}"
                            Background="{TemplateBinding Background}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition
                                            From="Unselected"
                                            To="UnselectedLocked"
                                            GeneratedDuration="0:0:0.33" />
                                        <VisualTransition
                                            From="UnselectedLocked"
                                            To="Unselected"
                                            GeneratedDuration="0:0:0.33" />
                                    </VisualStateGroup.Transitions>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemForegroundDisabled}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="Grid"
                                                Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemBackgroundDisabled}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unselected" />
                                    <VisualState x:Name="UnselectedLocked">
                                        <Storyboard>
                                            <DoubleAnimation
                                                Storyboard.TargetName="ContentPresenterTranslateTransform"
                                                Storyboard.TargetProperty="X"
                                                Duration="0"
                                                To="{ThemeResource PivotHeaderItemLockedTranslation}" />
                                            <DoubleAnimation
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="(UIElement.Opacity)"
                                                Duration="0"
                                                To="0" />
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemForegroundSelected}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="Grid"
                                                Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemBackgroundSelected}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="UnselectedPointerOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemForegroundUnselectedPointerOver}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="Grid"
                                                Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemBackgroundUnselectedPointerOver}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedPointerOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemForegroundSelectedPointerOver}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="Grid"
                                                Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemBackgroundSelectedPointerOver}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="UnselectedPressed">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemForegroundUnselectedPressed}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="Grid"
                                                Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemBackgroundUnselectedPressed}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedPressed">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="ContentPresenter"
                                                Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemForegroundSelectedPressed}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames
                                                Storyboard.TargetName="Grid"
                                                Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame
                                                    KeyTime="0"
                                                    Value="{ThemeResource PivotHeaderItemBackgroundSelectedPressed}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused" >
                                        <VisualState.Setters>
                                            <Setter Target="FocusPipe.Visibility" Value="Visible" />
                                        </VisualState.Setters>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused" />
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Grid.RenderTransform>
                                <TranslateTransform x:Name="ContentPresenterTranslateTransform" />
                            </Grid.RenderTransform>
                            <ContentPresenter Name="ContentPresenter"
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                                OpticalMarginAlignment="TrimSideBearings"
                                FontFamily="{TemplateBinding FontFamily}"
                                FontSize="{TemplateBinding FontSize}"
                                FontWeight="{TemplateBinding FontWeight}"
                                Content="{TemplateBinding Content}" />
                            <Rectangle Name="FocusPipe"
                                VerticalAlignment="Bottom"
                                HorizontalAlignment="Stretch"
                                Height="2"
                                Fill="{ThemeResource PivotHeaderItemFocusPipeFill}"
                                Visibility="Collapsed" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel Name="contentStackPanel"
            HorizontalAlignment="Left"
            VerticalAlignment="Top">
            <StackPanel
                Orientation="Horizontal"
                Margin="15 0" >
                <TextBlock Text="태스크 모니터"
                    FontSize="32" />
                <TextBlock Name="versionTextBlock"
                    Margin="5 0 0 0"
                    VerticalAlignment="Center"
                    FontSize="6" />
            </StackPanel>
            <Pivot Name="mainPivot"
                Margin="0 15 0 0"
                SelectionChanged="mainPivot_SelectionChanged">
                <PivotItem Name="processPivotItem" Tag="프로세스">
                    <PivotItem.Header>
                        <local:TabHeader Label="프로세스"
                            SelectedImage="/Assets/process-orange.png"
                            UnselectedImage="/Assets/process-grey.png" />
                    </PivotItem.Header>
                    <StackPanel 
                        Margin="10 10"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Top"
                        Orientation="Vertical">
                        <Grid Name="processHeaderGrid"
                            Margin="-10 0">
                            <Grid.Resources>
                                <Style TargetType="Button">
                                    <Setter Property="HorizontalAlignment"        Value="Stretch"  />
                                    <Setter Property="VerticalAlignment"          Value="Center"   />
                                    <Setter Property="Height"                     Value="24"       />
                                    <Setter Property="Padding"                    Value="10 0 0 0" />
                                    <Setter Property="HorizontalContentAlignment" Value="Left"     />
                                    <Setter Property="FontSize"                   Value="11"       />
                                </Style>
                            </Grid.Resources>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="200" />
                                <ColumnDefinition Width="40"  />
                                <ColumnDefinition Width="65"  />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="65"  />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="*"   />
                            </Grid.ColumnDefinitions>
                            <Button Grid.Column="0" Content="명칭"        Tag="ExecutableFileName" Click="processHeaderColumn_Click" />
                            <Button Grid.Column="1" Content="PID"         Tag="ProcessID"          Click="processHeaderColumn_Click" />
                            <Button Grid.Column="2" Content="커널 시간"   Tag="KernelTime"         Click="processHeaderColumn_Click" />
                            <Button Grid.Column="3" Content="사용자 시간" Tag="UserTime"           Click="processHeaderColumn_Click" />
                            <Button Grid.Column="4" Content="페이지 파일" Tag="PageFileSize"       Click="processHeaderColumn_Click" />
                            <Button Grid.Column="5" Content="작업 세트"   Tag="WorkingSetSize"     Click="processHeaderColumn_Click" />
                            <Button Grid.Column="6" Content="디스크 읽기" Tag="ReadByteCount"      Click="processHeaderColumn_Click" />
                            <Button Grid.Column="7" Content="디스크 쓰기" Tag="WriteByteCount"     Click="processHeaderColumn_Click" />
                            <Button Grid.Column="8" Content="타입"        Tag="AppType"            Click="processHeaderColumn_Click" />
                        </Grid>
                        <ListView Name="processListView"
                            Margin="-10 0"
                            ScrollViewer.VerticalScrollBarVisibility="Visible">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <Grid>
                                        <Grid.Resources>
                                            <Style TargetType="TextBlock">
                                                <Setter Property="FontSize"            Value="12"     />
                                                <Setter Property="HorizontalAlignment" Value="Left"   />
                                                <Setter Property="VerticalAlignment"   Value="Center" />
                                                <Setter Property="TextWrapping"        Value="Wrap"   />
                                            </Style>
                                        </Grid.Resources>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="30"  />
                                            <ColumnDefinition Width="170" />
                                            <ColumnDefinition Width="40"  />
                                            <ColumnDefinition Width="65"  />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="65"  />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="70"  />
                                        </Grid.ColumnDefinitions>
                                        <Rectangle Grid.Column="0"
                                            HorizontalAlignment="Left"
                                            VerticalAlignment="Top"
                                            Margin="0 2"
                                            Width="24"
                                            Height="24"
                                            Fill="LightGray" />
                                        <Image Grid.Column="0"
                                            HorizontalAlignment="Left"
                                            VerticalAlignment="Top"
                                            Margin="0 2"
                                            Width="24"
                                            Height="24"
                                            Source="{Binding Logo}" />
                                        <TextBlock Grid.Column="1"
                                            Text="{Binding ExecutableFileName, TargetNullValue=Unknown}" />
                                        <TextBlock Grid.Column="2"
                                            Text="{Binding ProcessID}" />
                                        <TextBlock Grid.Column="3"
                                            Text="{Binding KernelTime, Converter={StaticResource CPUTimeConverterKey}}" />
                                        <TextBlock Grid.Column="4"
                                            Text="{Binding UserTime, Converter={StaticResource CPUTimeConverterKey}}" />
                                        <TextBlock Grid.Column="5"
                                            Text="{Binding PageFileSize, Converter={StaticResource ByteToMegabyteConverterKey}}" />
                                        <TextBlock Grid.Column="6"
                                            Text="{Binding WorkingSetSize, Converter={StaticResource ByteToMegabyteConverterKey}}" />
                                        <TextBlock Grid.Column="7"
                                            Text="{Binding ReadByteCount, Converter={StaticResource ByteToMegabyteConverterKey}}" />
                                        <TextBlock Grid.Column="8"
                                            Text="{Binding WriteByteCount, Converter={StaticResource ByteToMegabyteConverterKey}}" />
                                        <TextBlock Grid.Column="9"
                                            Text="{Binding AppType}" />
                                    </Grid>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                        <StackPanel
                            Margin="0 10 0 0"
                            Orientation="Horizontal">
                            <TextBlock Text="진단 액세스 상태 : " />
                            <TextBlock
                                Margin="2 0 0 0"
                                Text="{Binding AccessStatus, Mode=OneWay}" />
                            <TextBlock
                                Margin="5 0 0 0"
                                Text="| 최근 업데이트 : " />
                            <TextBlock
                                Margin="2 0 0 0"
                                Text="{Binding ProcessLastUpdateTime,
                                    Mode=OneWay,
                                    Converter={StaticResource StringFormatConverterKey},
                                    ConverterParameter='{}{0:HH:mm:ss}'}" />
                            <TextBlock
                                Margin="5 0 0 0"
                                Text="| 조회 주기 : " />
                            <TextBlock
                                Margin="2 0 0 0"
                                Text="{Binding ProcessPollingInterval,
                                    Mode=OneWay,
                                    Converter={StaticResource StringFormatConverterKey},
                                    ConverterParameter='{}{0} 초'}" />
                        </StackPanel>
                    </StackPanel>
                </PivotItem>
                <PivotItem Name="appPivotItem" Tag="앱">
                    <PivotItem.Header>
                        <local:TabHeader Label="앱"
                            SelectedImage="/Assets/app-orange.png"
                            UnselectedImage="/Assets/app-grey.png" />
                    </PivotItem.Header>
                    <StackPanel 
                        HorizontalAlignment="Left"
                        VerticalAlignment="Top"
                        Margin="10 10"
                        Orientation="Vertical">
                        <Grid Name="appHeaderGrid"
                            Margin="-10 0">
                            <Grid.Resources>
                                <Style TargetType="Button">
                                    <Setter Property="HorizontalAlignment"        Value="Stretch"  />
                                    <Setter Property="VerticalAlignment"          Value="Center"   />
                                    <Setter Property="Height"                     Value="24"       />
                                    <Setter Property="Padding"                    Value="10 0 0 0" />
                                    <Setter Property="HorizontalContentAlignment" Value="Left"     />
                                    <Setter Property="FontSize"                   Value="11"       />
                                </Style>
                            </Grid.Resources>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="250" />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="75"  />
                                <ColumnDefinition Width="*"   />
                            </Grid.ColumnDefinitions>
                            <Button Grid.Column="0" Content="명칭"              Tag="Name"                Click="appHeaderColumn_Click" />
                            <Button Grid.Column="1" Content="커밋 제한"         Tag="CommitLimit"         Click="appHeaderColumn_Click" />
                            <Button Grid.Column="2" Content="전체 커밋"         Tag="TotalCommit"         Click="appHeaderColumn_Click" />
                            <Button Grid.Column="3" Content="개인 커밋"         Tag="PrivateCommit"       Click="appHeaderColumn_Click" />
                            <Button Grid.Column="4" Content="실행 상태"         Tag="ExecutionState"      Click="appHeaderColumn_Click" />
                            <Button Grid.Column="5" Content="에너지 상태"       Tag="EnergyQuotaState"    Click="appHeaderColumn_Click" />
                            <Button Grid.Column="6" Content="백그라운드 태스크" Tag="BackgroundTaskCount" Click="appHeaderColumn_Click" />
                        </Grid>
                        <ListView Name="appListView"
                            Margin="-10 0"
                            ScrollViewer.VerticalScrollBarVisibility="Visible">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <Grid>
                                        <Grid.Resources>
                                            <Style TargetType="TextBlock">
                                                <Setter Property="HorizontalAlignment" Value="Left"   />
                                                <Setter Property="VerticalAlignment"   Value="Center" />
                                                <Setter Property="TextWrapping"        Value="Wrap"   />
                                                <Setter Property="FontSize"            Value="12"     />
                                            </Style>
                                        </Grid.Resources>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="30"  />
                                            <ColumnDefinition Width="220" />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="75"  />
                                            <ColumnDefinition Width="75"  />
                                        </Grid.ColumnDefinitions>
                                        <Rectangle Grid.Column="0"
                                            HorizontalAlignment="Left"
                                            VerticalAlignment="Top"
                                            Margin="0 2"
                                            Width="24"
                                            Height="24"
                                            Fill="LightGray" />
                                        <Image Grid.Column="0"
                                            HorizontalAlignment="Left"
                                            VerticalAlignment="Top"
                                            Margin="0 2"
                                            Width="24"
                                            Height="24"
                                            Source="{Binding Logo}" />
                                        <TextBlock Grid.Column="1"
                                            Text="{Binding Name}" />
                                        <TextBlock Grid.Column="2"
                                            Text="{Binding CommitLimit, Converter={StaticResource MemoryLimitConverterKey}}" />
                                        <TextBlock Grid.Column="3"
                                            Text="{Binding TotalCommit, Converter={StaticResource ByteToMegabyteConverterKey}}" />
                                        <TextBlock Grid.Column="4"
                                            Text="{Binding PrivateCommit, Converter={StaticResource ByteToMegabyteConverterKey}}" />
                                        <TextBlock Grid.Column="5"
                                            Text="{Binding ExecutionState}" />
                                        <TextBlock Grid.Column="6"
                                            Text="{Binding EnergyQuotaState, Converter={StaticResource EnergyQuotaStateConverterKey}}" />
                                        <TextBlock Grid.Column="7"
                                            Text="{Binding BackgroundTaskCount, Converter={StaticResource NegativeValueConverterKey}}" />
                                    </Grid>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                        <StackPanel
                            Margin="0 10 0 0"
                            Orientation="Horizontal">
                            <TextBlock Text="진단 액세스 상태 : " />
                            <TextBlock
                                Margin="2 0 0 0"
                                Text="{Binding AccessStatus, Mode=OneWay}" />
                            <TextBlock
                                Margin="5 0 0 0"
                                Text="| 최근 업데이트 : " />
                            <TextBlock
                                Margin="2 0 0 0"
                                Text="{Binding AppLastUpdateTime,
                                    Mode=OneWay,
                                    Converter={StaticResource StringFormatConverterKey},
                                    ConverterParameter='{}{0:HH:mm:ss}'}" />
                            <TextBlock
                                Margin="5 0 0 0"
                                Text="| 조회 주기 : " />
                            <TextBlock
                                Margin="2 0 0 0"
                                Text="{Binding AppPollingInterval,
                                    Mode=OneWay,
                                    Converter={StaticResource StringFormatConverterKey},
                                    ConverterParameter='{}{0} sec'}" />
                        </StackPanel>
                    </StackPanel>
                </PivotItem>
                <PivotItem Name="detailPivotItem" Tag="앱 상세">
                    <PivotItem.Header>
                        <local:TabHeader Label="앱 상세"
                            SelectedImage="/Assets/details-orange.png"
                            UnselectedImage="/Assets/details-grey.png" />
                    </PivotItem.Header>
                    <Grid Margin="10 15 0 0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid Name="appInformationGrid" Grid.Row="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="300" />
                                <ColumnDefinition Width="*"   />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <TextBlock Grid.Row="0" Text="앱 진단 정보/앱 정보"
                                FontSize="18"
                                FontWeight="Bold" />
                            <TextBlock Grid.Row="1" Text="앱 정보"
                                FontSize="14"
                                FontWeight="Bold" />
                            <Rectangle Grid.Row="2"
                                HorizontalAlignment="Left"
                                VerticalAlignment="Top"
                                Margin="0 2"
                                Width="48"
                                Height="48"
                                Fill="LightGray" />
                            <Image Grid.Row="2"
                                HorizontalAlignment="Left"
                                VerticalAlignment="Top"
                                Margin="0 2" 
                                Width="48"
                                Height="48"
                                Source="{Binding Logo}" />
                            <TextBlock Grid.Row="3" Grid.Column="0" Text="앱 사용자 모델 ID" />
                            <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding AppUserModelID}" />
                            <TextBlock Grid.Row="4" Grid.Column="0" Text="ID" />
                            <TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding ID}" />
                            <TextBlock Grid.Row="5" Grid.Column="0" Text="패키지 패밀리명" />
                            <TextBlock Grid.Row="5" Grid.Column="1" Text="{Binding PackageFamilyName}" />
                            <TextBlock Grid.Row="6" Text="디스플레이 정보"
                                FontSize="14"
                                FontWeight="Bold" />
                            <TextBlock Grid.Row="7" Grid.Column="0" Text="디스플레이명" />
                            <TextBlock Grid.Row="7" Grid.Column="1" Text="{Binding DisplayName}" />
                            <TextBlock Grid.Row="8" Grid.Column="0" Text="설명" />
                            <TextBlock Grid.Row="8" Grid.Column="1" Text="{Binding Description}" />
                        </Grid>
                        <Button Name="freezeButton" Grid.Row="1"
                            Margin="0 4 0 0"
                            Width="100"
                            Content="동결"
                            Click="freezeButton_Click" />
                        <StackPanel Name="groupGrid" Grid.Row="2"
                            Margin="0 10 0 0">
                            <TextBlock Name="resourceGroupTextBlock"
                                FontSize="18"
                                FontWeight="Bold"
                                Text="리소스 그룹" />
                            <ListView Name="resourceGroupListView"
                                Height="100"
                                ScrollViewer.VerticalScrollBarVisibility="Visible">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <Grid>
                                            <Grid.Resources>
                                                <Style TargetType="TextBlock">
                                                    <Setter Property="FontSize"            Value="12"     />
                                                    <Setter Property="HorizontalAlignment" Value="Left"   />
                                                    <Setter Property="VerticalAlignment"   Value="Center" />
                                                    <Setter Property="TextWrapping"        Value="Wrap"   />
                                                </Style>
                                            </Grid.Resources>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="288" />
                                                <ColumnDefinition Width="*"   />
                                            </Grid.ColumnDefinitions>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                            </Grid.RowDefinitions>
                                            <TextBlock Grid.Row="0" Grid.Column="0" Text="리소스 그룹 정보 / 인스턴스 ID"
                                                FontSize="14"
                                                FontWeight="Bold" />
                                            <TextBlock Grid.Row="0" Grid.Column="1"
                                                FontSize="14"
                                                FontWeight="Bold"
                                                Text="{Binding InstanceID}" />
                                            <TextBlock Grid.Row="1" Grid.Column="0" Text="공유 여부" />
                                            <TextBlock Grid.Row="1" Grid.Column="1"
                                                Text="{Binding IsShared}" />
                                            <TextBlock Grid.Row="2" Text="메모리 리포트"
                                                FontSize="12"
                                                FontWeight="Bold" />
                                            <TextBlock Grid.Row="3" Grid.Column="0" Text="커밋 사용 레벨" />
                                            <TextBlock Grid.Row="3" Grid.Column="1"
                                                Text="{Binding CommitUsageLevel}" />
                                            <TextBlock Grid.Row="4" Grid.Column="0" Text="커밋 사용 제한" />
                                            <TextBlock Grid.Row="4" Grid.Column="1"
                                                Text="{Binding CommitUsageLimit, Converter={StaticResource MemoryLimitConverterKey}}" />
                                            <TextBlock Grid.Row="5" Grid.Column="0" Text="개인 커밋 사용" />
                                            <TextBlock Grid.Row="5" Grid.Column="1"
                                                Text="{Binding PrivateCommitUsage}" />
                                            <TextBlock Grid.Row="6" Grid.Column="0" Text="전체 커밋 사용" />
                                            <TextBlock Grid.Row="6" Grid.Column="1"
                                                Text="{Binding TotalCommitUsage}" />
                                            <TextBlock Grid.Row="7" Text="정적 리포트"
                                                FontSize="12"
                                                FontWeight="Bold" />
                                            <TextBlock Grid.Row="8" Grid.Column="0" Text="실행 상태" />
                                            <TextBlock Grid.Row="8" Grid.Column="1"
                                                Text="{Binding ExecutionState}" />
                                            <TextBlock Grid.Row="9" Grid.Column="0" Text="에너지 할당 상태" />
                                            <TextBlock Grid.Row="9" Grid.Column="1"
                                                Text="{Binding EnergyQuotaState}" />
                                        </Grid>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </StackPanel>
                        <StackPanel Grid.Row="3"
                            Margin="0 10 0 0">
                            <TextBlock Name="backgroundTaskTextBlock"
                                FontWeight="Bold"
                                FontSize="18"
                                Text="백그라운드 태스크 리포트" />
                            <ListView Name="backgroundTaskListView"
                                Height="100"
                                ScrollViewer.VerticalScrollBarVisibility="Visible">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <Grid>
                                            <Grid.Resources>
                                                <Style TargetType="TextBlock">
                                                    <Setter Property="HorizontalAlignment" Value="Left"   />
                                                    <Setter Property="VerticalAlignment"   Value="Center" />
                                                    <Setter Property="TextWrapping"        Value="Wrap"   />
                                                    <Setter Property="FontSize"            Value="12"     />
                                                </Style>
                                            </Grid.Resources>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="288" />
                                                <ColumnDefinition Width="*"   />
                                            </Grid.ColumnDefinitions>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                            </Grid.RowDefinitions>
                                            <TextBlock Grid.Row="0" Grid.Column="0" Text="명칭" />
                                            <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Name}" />
                                            <TextBlock Grid.Row="1" Grid.Column="0" Text="트리거" />
                                            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Trigger}" />
                                            <TextBlock Grid.Row="2" Grid.Column="0" Text="진입점" />
                                            <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding EntryPoint}" />
                                            <TextBlock Grid.Row="3" Grid.Column="0" Text="태스크 ID" />
                                            <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding TaskId}" />
                                        </Grid>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </StackPanel>
                        <StackPanel Grid.Row="4"
                            Margin="0 10 0 0">
                            <TextBlock Name="processDetailTextBlock"
                                FontSize="18"
                                FontWeight="Bold"
                                Text="프로세스" />
                            <ListView Name="processDetailListView"
                                Height="100"
                                ScrollViewer.VerticalScrollBarVisibility="Visible">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <Grid>
                                            <Grid.Resources>
                                                <Style TargetType="TextBlock">
                                                    <Setter Property="FontSize"            Value="12"     />
                                                    <Setter Property="HorizontalAlignment" Value="Left"   />
                                                    <Setter Property="VerticalAlignment"   Value="Center" />
                                                    <Setter Property="TextWrapping"        Value="Wrap"   />
                                                </Style>
                                            </Grid.Resources>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="288" />
                                                <ColumnDefinition Width="*"   />
                                            </Grid.ColumnDefinitions>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                                <RowDefinition Height="Auto" />
                                            </Grid.RowDefinitions>
                                            <TextBlock Grid.Row="0" Grid.Column="0" Text="프로세스 진단 정보 / 프로세스 ID"
                                                FontSize="14"
                                                FontWeight="Bold" />
                                            <TextBlock Grid.Row="0" Grid.Column="1"
                                                FontSize="14"
                                                FontWeight="Bold"
                                                Text="{Binding ProcessID}" />
                                            <TextBlock Grid.Row="1" Grid.Column="0" Text="실행 파일명" />
                                            <TextBlock Grid.Row="1" Grid.Column="1"
                                                Text="{Binding ExecutableFileName}" />
                                            <TextBlock Grid.Row="2" Grid.Column="0" Text="프로세스 시작 시간" />
                                            <TextBlock Grid.Row="2" Grid.Column="1"
                                                Text="{Binding ProcessStartTime}" />
                                            <TextBlock Grid.Row="3" Grid.Column="0" Text="프로세스 메모리 사용 리포트"
                                                FontSize="12"
                                                FontWeight="Bold" />
                                            <TextBlock Grid.Row="4" Grid.Column="0" Text="비페이지 풀 크기" />
                                            <TextBlock Grid.Row="4" Grid.Column="1"
                                                Text="{Binding NonPagedPoolSize}" />
                                            <TextBlock Grid.Row="5" Grid.Column="0" Text="페이지 풀 크기" />
                                            <TextBlock Grid.Row="5" Grid.Column="1"
                                                Text="{Binding PagedPoolSize}" />
                                            <TextBlock Grid.Row="6" Grid.Column="0" Text="페이지 폴트 카운트" />
                                            <TextBlock Grid.Row="6" Grid.Column="1"
                                                Text="{Binding PageFaultCount}" />
                                            <TextBlock Grid.Row="7" Grid.Column="0" Text="페이지 파일 크기" />
                                            <TextBlock Grid.Row="7" Grid.Column="1"
                                                Text="{Binding PageFileSize}" />
                                            <TextBlock Grid.Row="8" Grid.Column="0" Text="피크 비페이지 풀 크기" />
                                            <TextBlock Grid.Row="8" Grid.Column="1"
                                                Text="{Binding PeakNonPagedPoolSize}" />
                                            <TextBlock Grid.Row="9" Grid.Column="0" Text="피크 페이지 풀 크기" />
                                            <TextBlock Grid.Row="9" Grid.Column="1"
                                                Text="{Binding PeakPagedPoolSize}" />
                                            <TextBlock Grid.Row="10" Grid.Column="0" Text="피크 페이지 파일 크기" />
                                            <TextBlock Grid.Row="10" Grid.Column="1"
                                                Text="{Binding PeakPageFileSize}" />
                                            <TextBlock Grid.Row="11" Grid.Column="0" Text="피크 가상 메모리 크기" />
                                            <TextBlock Grid.Row="11" Grid.Column="1"
                                                Text="{Binding PeakVirtualMemorySize}" />
                                            <TextBlock Grid.Row="12" Grid.Column="0" Text="피크 작업 세트 크기" />
                                            <TextBlock Grid.Row="12" Grid.Column="1"
                                                Text="{Binding PeakWorkingSetSize}" />
                                            <TextBlock Grid.Row="13" Grid.Column="0" Text="개인 페이지 카운트" />
                                            <TextBlock Grid.Row="13" Grid.Column="1"
                                                Text="{Binding PrivatePageCount}" />
                                            <TextBlock Grid.Row="14" Grid.Column="0" Text="가상 메모미 크기" />
                                            <TextBlock Grid.Row="14" Grid.Column="1"
                                                Text="{Binding VirtualMemorySize}" />
                                            <TextBlock Grid.Row="15" Grid.Column="0" Text="작업 세트 크기" />
                                            <TextBlock Grid.Row="15" Grid.Column="1"
                                                Text="{Binding WorkingSetSize}" />
                                            <TextBlock Grid.Row="16" Grid.Column="0" Text="프로세스 CPU 사용 리포트"
                                                FontSize="12"
                                                FontWeight="Bold" />
                                            <TextBlock Grid.Row="17" Grid.Column="0" Text="커널 시간" />
                                            <TextBlock Grid.Row="17" Grid.Column="1"
                                                Text="{Binding KernelTime}" />
                                            <TextBlock Grid.Row="18" Grid.Column="0" Text="사용자 시간" />
                                            <TextBlock Grid.Row="18" Grid.Column="1"
                                                Text="{Binding UserTime}" />
                                            <TextBlock Grid.Row="19" Grid.Column="0" Text="프로세스 디스크 사용 리포트"
                                                FontSize="12"
                                                FontWeight="Bold" />
                                            <TextBlock Grid.Row="20" Grid.Column="0" Text="읽기 바이트 카운트" />
                                            <TextBlock Grid.Row="20" Grid.Column="1"
                                                Text="{Binding ReadByteCount}" />
                                            <TextBlock Grid.Row="21" Grid.Column="0" Text="쓰기 바이트 카운트" />
                                            <TextBlock Grid.Row="21" Grid.Column="1"
                                                Text="{Binding WriteByteCount}" />
                                            <TextBlock Grid.Row="22" Grid.Column="0" Text="기타 바이트 카운트" />
                                            <TextBlock Grid.Row="22" Grid.Column="1"
                                                Text="{Binding OtherByteCount}" />
                                            <TextBlock Grid.Row="23" Grid.Column="0" Text="기타 연산 카운트" />
                                            <TextBlock Grid.Row="23" Grid.Column="1"
                                                Text="{Binding OtherOperationCount}" />
                                            <TextBlock Grid.Row="24" Grid.Column="0" Text="읽기 연산 카운트" />
                                            <TextBlock Grid.Row="24" Grid.Column="1"
                                                Text="{Binding ReadOperationCount}" />
                                            <TextBlock Grid.Row="25" Grid.Column="0" Text="쓰기 연산 카운트" />
                                            <TextBlock Grid.Row="25" Grid.Column="1"
                                                Text="{Binding WriteOperationCount}" />
                                        </Grid>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </StackPanel>
                    </Grid>
                </PivotItem>
                <PivotItem x:Name="systemPivotItem" Tag="시스템">
                    <PivotItem.Header>
                        <local:TabHeader Label="시스템"
                            SelectedImage="/Assets/system-orange.png"
                            UnselectedImage="/Assets/system-grey.png" />
                    </PivotItem.Header>
                    <Grid Margin="5 15 0 0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid Name="staticDataGrid" Grid.Row="1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="140" />
                                <ColumnDefinition Width="*"   />
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Text="머신"
                                FontWeight="Bold"
                                FontSize="14" />
                            <TextBlock Grid.Row="1" Grid.Column="0" Text="머신명" />
                            <TextBlock Grid.Row="1" Grid.Column="1"
                                Text="{Binding MachineName}" />
                            <TextBlock Grid.Row="2" Grid.Column="0" Text="제조 &amp; 모델" />
                            <TextBlock Grid.Row="2" Grid.Column="1"
                                Text="{Binding MakeModel}" />
                            <TextBlock Grid.Row="3" Grid.Column="0" Text="장치 폼 팩터" />
                            <TextBlock Grid.Row="3" Grid.Column="1"
                                Text="{Binding FormFactor}" />
                            <TextBlock Grid.Row="4" Grid.Column="0" Text="OS 버전" />
                            <TextBlock Grid.Row="4" Grid.Column="1"
                                Text="{Binding OSVersion}" />
                            <TextBlock Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" Text="CPU"
                                Margin="0 5 0 0"
                                FontWeight="Bold"
                                FontSize="14" />
                            <TextBlock Grid.Row="6" Grid.Column="0" Text="논리적 프로세서 수" />
                            <TextBlock Grid.Row="6" Grid.Column="1"
                                Text="{Binding LogicalProcessorCount}" />
                            <TextBlock Grid.Row="7" Grid.Column="0" Text="프로세서" />
                            <TextBlock Grid.Row="7" Grid.Column="1"
                                Text="{Binding Processor}" />
                            <TextBlock Grid.Row="8" Grid.Column="0" Text="페이지 크기" />
                            <TextBlock Grid.Row="8" Grid.Column="1"
                                Text="{Binding PageSize}" />
                        </Grid>
                        <Grid Name="dynamicDataGrid" Grid.Row="2"
                            Margin="0 5 0 0">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="140" />
                                <ColumnDefinition Width="*"   />
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Text="메모리"
                                FontWeight="Bold"
                                FontSize="14" />
                            <TextBlock Grid.Row="1" Grid.Column="0" Text="물리" />
                            <TextBlock Grid.Row="1" Grid.Column="1"
                                Text="{Binding PhysicalMemory}" />
                            <TextBlock Grid.Row="2" Grid.Column="0" Text="페이지 파일 + 물리" />
                            <TextBlock Grid.Row="2" Grid.Column="1"
                                Text="{Binding PhysicalPlusPageFile}" />
                            <TextBlock Grid.Row="3" Grid.Column="0" Text="가상" />
                            <TextBlock Grid.Row="3" Grid.Column="1"
                                Text="{Binding VirtualMemory}" />
                            <TextBlock Grid.Row="4" Grid.Column="0" Text="디스크상 페이지 파일" />
                            <TextBlock Grid.Row="4" Grid.Column="1"
                                Text="{Binding PageFileOnDisk}" />
                            <TextBlock Grid.Row="5" Grid.Column="0" Text="메모리 사용" />
                            <TextBlock Grid.Row="5" Grid.Column="1"
                                Text="{Binding MemoryLoad}" />
                            <TextBlock Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2" Text="전원/배터리"
                                Margin="0 5 0 0"
                                FontWeight="Bold"
                                FontSize="14" />
                            <TextBlock Grid.Row="7" Grid.Column="0" Text="AC 라인 상태" />
                            <TextBlock Grid.Row="7" Grid.Column="1"
                                Text="{Binding ACLineStatus}" />
                            <TextBlock Grid.Row="8" Grid.Column="0" Text="배터리 충전 상태" />
                            <TextBlock Grid.Row="8" Grid.Column="1"
                                Text="{Binding BatteryChargeStatus}" />
                            <TextBlock Grid.Row="9" Grid.Column="0" Text="배터리 수명" />
                            <TextBlock Grid.Row="9" Grid.Column="1"
                                Text="{Binding BatteryLife}" />
                            <TextBlock Grid.Row="10" Grid.Column="0" Text="배터리 세이버" />
                            <TextBlock Grid.Row="10" Grid.Column="1"
                                Text="{Binding BatterySaver}" />
                            <TextBlock Grid.Row="11" Grid.Column="0" Text="충전율" />
                            <TextBlock Grid.Row="11" Grid.Column="1"
                                Text="{Binding ChargeRate}" />
                            <TextBlock Grid.Row="12" Grid.Column="0" Text="용량" />
                            <TextBlock Grid.Row="12" Grid.Column="1"
                                Text="{Binding Capacity}" />
                            <TextBlock Grid.Row="13" Grid.Column="0" Grid.ColumnSpan="2" Text="디스크"
                                Margin="0 5 0 0"
                                FontWeight="Bold"
                                FontSize="14" />
                            <TextBlock Grid.Row="14" Grid.Column="0" Text="전체 디스크 크기" />
                            <TextBlock Grid.Row="14" Grid.Column="1"
                                Text="{Binding TotalDiskSize}" />
                            <TextBlock Grid.Row="15" Grid.Column="0" Text="잔여 공간" />
                            <TextBlock Grid.Row="15" Grid.Column="1"
                                Text="{Binding DiskFreeSpace}" />
                            <TextBlock Grid.Row="16" Grid.Column="0" Grid.ColumnSpan="2" Text="네트워크"
                                Margin="0 5 0 0"
                                FontWeight="Bold"
                                FontSize="14" />
                            <TextBlock Grid.Row="17" Grid.Column="0" Text="도메인명" />
                            <TextBlock Grid.Row="17" Grid.Column="1"
                                Text="{Binding DomainName}" />
                            <TextBlock Grid.Row="18" Grid.Column="0" Text="노드 타입" />
                            <TextBlock Grid.Row="18" Grid.Column="1"
                                Text="{Binding NodeType}" />
                            <TextBlock Grid.Row="19" Grid.Column="0" Text="연결 프로필" />                            
                            <TextBlock Grid.Row="19" Grid.Column="1"
                                Text="{Binding ConnectedProfile}" />
                            <TextBlock Grid.Row="20" Grid.Column="0" Text="IANA 인터페이스 타입" />
                            <TextBlock Grid.Row="20" Grid.Column="1"
                                Text="{Binding IANAInterfaceType}" />
                            <TextBlock Grid.Row="21" Grid.Column="0" Text="인바운드 속도" />
                            <TextBlock Grid.Row="21" Grid.Column="1"
                                Text="{Binding InboundSpeed}" />
                            <TextBlock Grid.Row="22" Grid.Column="0" Text="아웃바운드 속도" />
                            <TextBlock Grid.Row="22" Grid.Column="1"
                                Text="{Binding OutboundSpeed}" />
                            <TextBlock Grid.Row="23" Grid.Column="0" Text="호스트 주소" />
                            <TextBlock Grid.Row="23" Grid.Column="1"
                                Text="{Binding HostAddress}" />
                            <TextBlock Grid.Row="24" Grid.Column="0" Text="주소 타입" />
                            <TextBlock Grid.Row="24" Grid.Column="1"
                                Text="{Binding AddressType}" />
                        </Grid>
                    </Grid>
                </PivotItem>
                <PivotItem Name="settingPivotItem" Tag="설정">
                    <PivotItem.Header>
                        <local:TabHeader Label="설정"
                            SelectedImage="/Assets/settings-orange.png"
                            UnselectedImage="/Assets/settings-grey.png" />
                    </PivotItem.Header>
                    <StackPanel Name="settingsGrid"
                        VerticalAlignment="Center"
                        Margin="10 35 0 0"
                        Orientation="Horizontal">
                        <Slider Name="processIntervalSlider"
                            VerticalAlignment="Center"
                            Margin="0 0 5 0"
                            Width="200"
                            BorderThickness="0"
                            Header="프로세스 조회 주기 (초)"
                            TickPlacement="TopLeft"
                            Minimum="0"
                            Maximum="60"
                            FontSize="12"
                            Value="{Binding ProcessPollingInterval, Mode=TwoWay}" />
                        <Slider Name="appIntervalSlider"
                            VerticalAlignment="Center"
                            Margin="0 0 5 0"
                            Width="200"
                            BorderThickness="0"
                            Header="앱 조회 주기 (초)"
                            TickPlacement="TopLeft"
                            Minimum="0"
                            Maximum="60"
                            FontSize="12"
                            Value="{Binding AppPollingInterval, Mode=TwoWay}" />
                        <Slider Name="systemIntervalSlider"
                            VerticalAlignment="Center"
                            Margin="0 0 5 0"
                            Width="200"
                            BorderThickness="0"
                            Header="시스템 조회 주기 (초)"
                            TickPlacement="TopLeft"
                            Minimum="0" 
                            Maximum="60"
                            FontSize="12"
                            Value="{Binding SystemPollingInterval, Mode=TwoWay}" />
                    </StackPanel>
                </PivotItem>
            </Pivot>
        </StackPanel>
    </Grid>
</Page>

 

▶ MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using Windows.Devices.Power;
using Windows.Networking.Connectivity;
using Windows.Networking;
using Windows.Security.ExchangeActiveSyncProvisioning;
using Windows.Storage;
using Windows.System;
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>
    public sealed partial class MainPage : Page, INotifyPropertyChanged
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 속성 변경시 이벤트 - PropertyChanged

        /// <summary>
        /// 속성 변경시 이벤트
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// GB
        /// </summary>
        private const double GB = 1073741824; // 1024 * 1024 * 1024;

        /// <summary>
        /// MBPS
        /// </summary>
        private const double MBPS = 1000000;

        /// <summary>
        /// 목록 높이 오프셋
        /// </summary>
        private const int LIST_HEIGHT_OFFSET = 200;

        /// <summary>
        /// 스크롤바 너비 오프셋
        /// </summary>
        private const int SCROLLBAR_WIDTH_OFFSET = 24;

        /// <summary>
        /// 디폴트 앱 리스트 타이머 주기
        /// </summary>
        private const int DEFAULT_APP_LIST_TIMER_INTERVAL = 5;

        /// <summary>
        /// 디폴트 프로세스 리스트 타이머 주기
        /// </summary>
        private const int DEFAULT_PROCESS_LIST_TIMER_INTERVAL = 30;

        /// <summary>
        /// 디폴트 피봇명
        /// </summary>
        private const string DEFAULT_PIVOT_NAME = "프로세스";

        /// <summary>
        /// 진단 액세스 상태
        /// </summary>
        private DiagnosticAccessStatus accessStatus;

        /// <summary>
        /// 프로세스 마지막 업데이트 시간
        /// </summary>
        private DateTime processLastUpdateTime;

        /// <summary>
        /// 앱 마지막 업데이트 시간
        /// </summary>
        private DateTime appLastUpdateTime;

        /// <summary>
        /// 프로세스 조회 주기
        /// </summary>
        private int processPollingInterval;

        /// <summary>
        /// 앱 조회 주기
        /// </summary>
        private int appPollingInterval;

        /// <summary>
        /// 시스템 조회 주기
        /// </summary>
        private int systemPollingInterval;

        /// <summary>
        /// 프로세스 컬렉션
        /// </summary>
        private ProcessCollection processCollection = new ProcessCollection();

        /// <summary>
        /// 앱 컬렉션
        /// </summary>
        private AppCollection appCollection = new AppCollection();

        /// <summary>
        /// 프로세스 업데이트 타이머
        /// </summary>
        private DispatcherTimer processUpdateTimer;

        /// <summary>
        /// 앱 업데이트 타이머
        /// </summary>
        private DispatcherTimer appUpdateTimer;

        /// <summary>
        /// 시스템 업데이트 타이머
        /// </summary>
        private DispatcherTimer systemUpdateTimer;

        /// <summary>
        /// 프로세스 정렬 컬럼
        /// </summary>
        private string processSortColumn = "ExecutableFileName";

        /// <summary>
        /// 앱 정렬 컬럼
        /// </summary>
        private string appSortColumn = "Name";

        /// <summary>
        /// 상세 포커스 여부
        /// </summary>
        private bool isFocusOnDetail = false;

        /// <summary>
        /// 상세 앱
        /// </summary>
        private AppModel detailApp;

        /// <summary>
        /// 동결 여부
        /// </summary>
        private bool isFrozen;

        /// <summary>
        /// 정적 시스템 정보 초기화 여부
        /// </summary>
        private bool isStaticSystemInformationInitialized;

        /// <summary>
        /// 앱 프로세스 태스크
        /// </summary>
        private AppProcessTaskModel appProcessTask;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 진단 액세스 상태 - AccessStatus

        /// <summary>
        /// 진단 액세스 상태
        /// </summary>
        public DiagnosticAccessStatus AccessStatus
        {
            get
            {
                return this.accessStatus;
            }
            set
            {
                if(this.accessStatus != value)
                {
                    this.accessStatus = value;

                    FirePropertyChangedEvent("AccessStatus");
                }
            }
        }

        #endregion
        #region 프로세스 마지막 업데이트 시간 - ProcessLastUpdateTime

        /// <summary>
        /// 프로세스 마지막 업데이트 시간
        /// </summary>
        public DateTime ProcessLastUpdateTime
        {
            get
            {
                return this.processLastUpdateTime;
            }
            set
            {
                if(this.processLastUpdateTime != value)
                {
                    this.processLastUpdateTime = value;

                    FirePropertyChangedEvent("ProcessLastUpdateTime");
                }
            }
        }

        #endregion
        #region 앱 마지막 업데이트 시간 - AppLastUpdateTime

        /// <summary>
        /// 앱 마지막 업데이트 시간
        /// </summary>
        public DateTime AppLastUpdateTime
        {
            get
            {
                return this.appLastUpdateTime;
            }
            set
            {
                if(this.appLastUpdateTime != value)
                {
                    this.appLastUpdateTime = value;

                    FirePropertyChangedEvent("AppLastUpdateTime");
                }
            }
        }

        #endregion
        #region 프로세스 조회 주기 - ProcessPollingInterval

        /// <summary>
        /// 프로세스 조회 주기
        /// </summary>
        public int ProcessPollingInterval
        {
            get
            {
                return this.processPollingInterval;
            }
            set
            {
                if(this.processPollingInterval != value)
                {
                    this.processPollingInterval = value;

                    FirePropertyChangedEvent("ProcessPollingInterval");
                }
            }
        }

        #endregion
        #region 앱 조회 주기 - AppPollingInterval

        /// <summary>
        /// 앱 조회 주기
        /// </summary>
        public int AppPollingInterval
        {
            get
            {
                return this.appPollingInterval;
            }
            set
            {
                if(this.appPollingInterval != value)
                {
                    this.appPollingInterval = value;

                    FirePropertyChangedEvent("AppPollingInterval");
                }
            }
        }

        #endregion
        #region 시스템 조회 주기 - SystemPollingInterval

        /// <summary>
        /// 시스템 조회 주기
        /// </summary>
        public int SystemPollingInterval
        {
            get
            {
                return this.systemPollingInterval;
            }
            set
            {
                if(this.systemPollingInterval != value)
                {
                    this.systemPollingInterval = value;

                    FirePropertyChangedEvent("SystemPollingInterval");
                }
            }
        }

        #endregion

        #region 동적 시스템 - DynamicSystem

        /// <summary>
        /// 동적 시스템
        /// </summary>
        public DynamicSystemModel DynamicSystem { get; internal set; }

        #endregion
        #region 정적 시스템 - StaticSystem

        /// <summary>
        /// 정적 시스템
        /// </summary>
        public StaticSystemModel StaticSystem { get; internal set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 생성자 - MainPage()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainPage()
        {
            AccessStatus           = DiagnosticAccessStatus.Unspecified;
            ProcessLastUpdateTime  = DateTime.MinValue;
            AppLastUpdateTime      = DateTime.MinValue;
            ProcessPollingInterval = DEFAULT_PROCESS_LIST_TIMER_INTERVAL;
            AppPollingInterval     = DEFAULT_APP_LIST_TIMER_INTERVAL;
            SystemPollingInterval  = DEFAULT_PROCESS_LIST_TIMER_INTERVAL;

            InitializeComponent();

            this.versionTextBlock.Text = App.VersionString;

            this.contentStackPanel.DataContext = this;

            App.ActivateDisplayRequest();
 
            ApplicationView.GetForCurrentView().Title = DEFAULT_PIVOT_NAME;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Protected
        //////////////////////////////////////////////////////////////////////////////// Function

        #region 탐색되는 경우 처리하기 - OnNavigatedTo(e)

        /// <summary>
        /// 탐색되는 경우 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            AccessStatus = await this.appCollection.GetAccessStatusAsync();

            this.processListView.ItemsSource = this.processCollection;

            this.appListView.ItemsSource = this.appCollection;
        }

        #endregion
        #region 탐색하는 경우 처리하기 - OnNavigatedFrom(e)

        /// <summary>
        /// 탐색하는 경우 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            StopProcessPolling();

            StopAppPolling();

            StopSystemPolling();
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 페이지 크기 변경시 처리하기 - Page_SizeChanged(sender, e)

        /// <summary>
        /// 페이지 크기 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            double windowWidth  = Window.Current.Bounds.Width;
            double windowHeight = Window.Current.Bounds.Height;

            this.processHeaderGrid.Width = windowWidth;

            this.processListView.Width  = windowWidth  - SCROLLBAR_WIDTH_OFFSET;
            this.processListView.Height = windowHeight - LIST_HEIGHT_OFFSET;

            this.appHeaderGrid.Width = windowWidth;

            this.appListView.Width  = windowWidth  - SCROLLBAR_WIDTH_OFFSET;
            this.appListView.Height = windowHeight - LIST_HEIGHT_OFFSET;
        }

        #endregion
        #region 프로세스 업데이트 타이머 틱 처리하기 - processUpdateTimer_Tick(sender, e)

        /// <summary>
        /// 프로세스 업데이트 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void processUpdateTimer_Tick(object sender, object e)
        {
            UpdateProcessData();
        }

        #endregion
        #region 앱 업데이트 타이머 틱 처리하기 - appUpdateTimer_Tick(sender, e)

        /// <summary>
        /// 앱 업데이트 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void appUpdateTimer_Tick(object sender, object e)
        {
            UpdateAppData();
        }

        #endregion
        #region 시스템 업데이트 타이머 틱 처리하기 - systemUpdateTimer_Tick(sender, e)

        /// <summary>
        /// 시스템 업데이트 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void systemUpdateTimer_Tick(object sender, object e)
        {
            UpdateSystemData();
        }

        #endregion
        #region 메인 피벗 선택 변경시 처리하기 - mainPivot_SelectionChanged(sender, e)

        /// <summary>
        /// 메인 피벗 선택 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void mainPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            PivotItem selectedPivotItem = this.mainPivot.SelectedItem as PivotItem;

            App.WriteLog("mainPivot_SelectionChanged", "PivotItem.Name", selectedPivotItem.Name);

            foreach(PivotItem pivotItem in mainPivot.Items)
            {
                if(pivotItem == selectedPivotItem)
                {
                    TabHeader tabHeader = pivotItem.Header as TabHeader;

                    if(tabHeader != null)
                    {
                        tabHeader.SetSelectedItem(true);
                    }
                }
                else
                {
                    TabHeader tabHeader = pivotItem.Header as TabHeader;

                    if(tabHeader != null)
                    {
                        tabHeader.SetSelectedItem(false);
                    }
                }
            }

            ApplicationView.GetForCurrentView().Title = selectedPivotItem.Tag.ToString();

            switch(selectedPivotItem.Name)
            {
                case "processPivotItem" :

                    this.isFocusOnDetail = false;

                    StopAppPolling();

                    StopSystemPolling();

                    UpdateProcessData();

                    InitializeProcessPolling();

                    break;

                case "appPivotItem" :

                    this.isFocusOnDetail = false;

                    StopProcessPolling();

                    StopSystemPolling();

                    UpdateAppData();

                    InitializeAppPolling();

                    break;

                case "detailPivotItem" :

                    StopProcessPolling();

                    StopSystemPolling();

                    AppModel app = appListView.SelectedItem as AppModel;

                    if(app != null && app.ADI != null)
                    {
                        this.detailApp = app;

                        this.isFocusOnDetail = true;

                        UpdateDetail();
                    }

                    StopAppPolling();

                    this.freezeButton.Content = "동결 해제";

                    isFrozen = true;

                    break;

                case "systemPivotItem" :

                    this.isFocusOnDetail = false;

                    StopAppPolling();

                    StopProcessPolling();

                    if(!this.isStaticSystemInformationInitialized)
                    {
                        GetStaticSystemInformation();

                        this.isStaticSystemInformationInitialized = true;
                    }

                    UpdateSystemData();

                    InitializeSystemPolling();

                    break;

                case "settingPivotItem" :

                    this.isFocusOnDetail = false;

                    StopAppPolling();

                    StopProcessPolling();

                    StopSystemPolling();

                    break;
            }
        }

        #endregion
        #region 프로세스 헤더 컬럼 클릭시 처리하기 - processHeaderColumn_Click(sender, e)

        /// <summary>
        /// 프로세스 헤더 컬럼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void processHeaderColumn_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;

            if(button != null)
            {
                this.processSortColumn = (string)button.Tag;

                this.processCollection.Sort(this.processSortColumn, true);
            }
        }

        #endregion
        #region 앱 헤더 컬럼 클릭시 처리하기 - appHeaderColumn_Click(sender, e)

        /// <summary>
        /// 앱 헤더 컬럼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void appHeaderColumn_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;

            if(button != null)
            {
                this.appSortColumn = (string)button.Tag;

                this.appCollection.Sort(this.appSortColumn, true);
            }
        }

        #endregion
        #region 동결 버튼 클릭시 처리하기 - freezeButton_Click(sender, e)

        /// <summary>
        /// 동결 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void freezeButton_Click(object sender, RoutedEventArgs e)
        {
            this.isFrozen = !this.isFrozen;

            if(this.isFrozen)
            {
                StopAppPolling();

                this.freezeButton.Content = "동결 해제";
            }
            else
            {
                InitializeAppPolling();

                this.freezeButton.Content = "동결";
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propertyName)

        /// <summary>
        /// 속성 변경시 이벤트 발생시키기
        /// </summary>
        /// <param name="propertyName">속성명</param>
        private void FirePropertyChangedEvent(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region 프로세스 조회 초기화하기 - InitializeProcessPolling()

        /// <summary>
        /// 프로세스 조회 초기화하기
        /// </summary>
        private void InitializeProcessPolling()
        {
            if(this.processUpdateTimer != null)
            {
                this.processUpdateTimer.Stop();

                this.processUpdateTimer = null;
            }

            if(ProcessPollingInterval != 0)
            {
                this.processUpdateTimer = new DispatcherTimer()
                {
                    Interval = TimeSpan.FromSeconds(ProcessPollingInterval)
                };

                this.processUpdateTimer.Tick += processUpdateTimer_Tick;

                this.processUpdateTimer.Start();
            }
        }

        #endregion
        #region 프로세스 데이터 업데이트하기 - UpdateProcessData()

        /// <summary>
        /// 프로세스 데이터 업데이트하기
        /// </summary>
        private void UpdateProcessData()
        {
            this.processCollection.Update();

            this.processCollection.Sort(processSortColumn, false);

            ProcessLastUpdateTime = DateTime.Now;
        }

        #endregion
        #region 프로세스 조회 중단하기 - StopProcessPolling()

        /// <summary>
        /// 프로세스 조회 중단하기
        /// </summary>
        private void StopProcessPolling()
        {
            if(this.processUpdateTimer != null)
            {
                this.processUpdateTimer.Stop();

                this.processUpdateTimer = null;

                this.processCollection.Clear();
            }
        }

        #endregion

        #region 앱 조회 초기화하기 - InitializeAppPolling()

        /// <summary>
        /// 앱 조회 초기화하기
        /// </summary>
        private void InitializeAppPolling()
        {
            if(this.appUpdateTimer != null)
            {
                this.appUpdateTimer.Stop();

                this.appUpdateTimer = null;
            }

            if(AppPollingInterval != 0)
            {
                this.appUpdateTimer = new DispatcherTimer()
                {
                    Interval = TimeSpan.FromSeconds(AppPollingInterval)
                };

                this.appUpdateTimer.Tick += appUpdateTimer_Tick;

                this.appUpdateTimer.Start();
            }
        }

        #endregion
        #region 앱 데이터 업데이트하기 - UpdateAppData()

        /// <summary>
        /// 앱 데이터 업데이트하기
        /// </summary>
        private void UpdateAppData()
        {
            if(this.isFocusOnDetail)
            {
                UpdateDetail();
            }
            else
            {
                bool isAppAdded = this.appCollection.Update();

                if(isAppAdded)
                {
                    this.appCollection.Sort(this.appSortColumn, false);
                }

                AppLastUpdateTime = DateTime.Now;
            }
        }

        #endregion
        #region 앱 조회 중단하기 - StopAppPolling()

        /// <summary>
        /// 앱 조회 중단하기
        /// </summary>
        private void StopAppPolling()
        {
            if(this.appUpdateTimer != null)
            {
                this.appUpdateTimer.Stop();

                this.appUpdateTimer = null;

                this.appCollection.Clear();
            }
        }

        #endregion

        #region 시스템 조회 초기화하기 - InitializeSystemPolling()

        /// <summary>
        /// 시스템 조회 초기화하기
        /// </summary>
        private void InitializeSystemPolling()
        {
            if(this.systemUpdateTimer != null)
            {
                this.systemUpdateTimer.Stop();

                this.systemUpdateTimer = null;
            }

            if(SystemPollingInterval != 0)
            {
                this.systemUpdateTimer = new DispatcherTimer()
                {
                    Interval = TimeSpan.FromSeconds(SystemPollingInterval)
                };

                this.systemUpdateTimer.Tick += systemUpdateTimer_Tick;

                this.systemUpdateTimer.Start();
            }
        }

        #endregion
        #region 시스템 데이터 업데이트하기 - UpdateSystemData()

        /// <summary>
        /// 시스템 데이터 업데이트하기
        /// </summary>
        private void UpdateSystemData()
        {
            DynamicSystem = new DynamicSystemModel();

            try
            {
                MEMORYSTATUSEX memoryStatus = new MEMORYSTATUSEX();

                WIN32Helper.GlobalMemoryStatusEx(memoryStatus);

                DynamicSystem.PhysicalMemory       = $"total = {memoryStatus.TotalPhysicalMemorySize / GB:N2} GB, " +
                                                     $"available = {memoryStatus.AvailablePhysicalMemorySize / GB:N2} GB";
                DynamicSystem.PhysicalPlusPageFile = $"total = {memoryStatus.TotalPageFileSize       / GB:N2} GB, " +
                                                     $"available = {memoryStatus.AvailablePageFileSize       / GB:N2} GB";
                DynamicSystem.VirtualMemory        = $"total = {memoryStatus.TotalVirtualMemorySize  / GB:N2} GB, " +
                                                     $"available = {memoryStatus.AvailableVirtualMemorySize  / GB:N2} GB";
                DynamicSystem.PageFileOnDisk       = $"{memoryStatus.TotalPageFileSize - memoryStatus.TotalPhysicalMemorySize / GB:N2} GB";
                DynamicSystem.MemoryLoad           = $"{memoryStatus.MemoryLoad}%";
            }
            catch(Exception exception)
            {
                App.WriteLog("MainPage.UpdateSystemData", "MEMORYSTATUSEX", exception.Message);
            }

            bool isBatteryAvailable = true;

            try
            {
                SYSTEM_POWER_STATUS powerStatus = new SYSTEM_POWER_STATUS();

                WIN32Helper.GetSystemPowerStatus(ref powerStatus);

                DynamicSystem.ACLineStatus        = powerStatus.ACLineStatus.ToString();
                DynamicSystem.BatteryChargeStatus = $"{powerStatus.BatteryChargeStatus:G}";

                if(powerStatus.BatteryChargeStatus == BatteryFlag.NoSystemBattery || powerStatus.BatteryChargeStatus == BatteryFlag.Unknown)
                {
                    isBatteryAvailable = false;

                    DynamicSystem.BatteryLife = "n/a";
                }
                else
                {
                    DynamicSystem.BatteryLife = $"{powerStatus.BatteryLifePercent}%";
                }

                DynamicSystem.BatterySaver = powerStatus.BatterySaver.ToString();
            }
            catch(Exception exception)
            {
                App.WriteLog("MainPage.UpdateSystemData", "SYSTEM_POWER_STATUS", exception.Message);
            }

            if(isBatteryAvailable)
            {
                try
                {
                    Battery battery = Battery.AggregateBattery;

                    BatteryReport batteryReport = battery.GetReport();

                    DynamicSystem.ChargeRate = $"{batteryReport.ChargeRateInMilliwatts:N0} mW";
                    DynamicSystem.Capacity   = $"design = {batteryReport.DesignCapacityInMilliwattHours:N0} mWh, "   +
                                               $"full = {batteryReport.FullChargeCapacityInMilliwattHours:N0} mWh, " +
                                               $"remaining = {batteryReport.RemainingCapacityInMilliwattHours:N0} mWh";
                }
                catch(Exception exception)
                {
                    App.WriteLog("MainPage.UpdateSystemData", "BatteryReport", exception.Message);
                }
            }
            else
            {
                DynamicSystem.ChargeRate = "n/a";
                DynamicSystem.Capacity   = "n/a";
            }

            try
            {
                ulong userFreeByteCount;
                ulong userTotalByteCount;
                ulong totalFreeByteCount;

                IStorageFolder storageFolder = ApplicationData.Current.LocalFolder;

                WIN32Helper.GetDiskFreeSpaceEx(storageFolder.Path, out userFreeByteCount, out userTotalByteCount, out totalFreeByteCount);

                DynamicSystem.TotalDiskSize = $"{userTotalByteCount / GB:N2} GB";
                DynamicSystem.DiskFreeSpace = $"{userFreeByteCount  / GB:N2} GB";
            }
            catch(Exception exception)
            {
                App.WriteLog("MainPage.UpdateSystemData", "GetDiskFreeSpaceEx", exception.Message);
            }

            try
            {
                IntPtr bufferHandle = IntPtr.Zero;
                uint   bufferLength = (uint)Marshal.SizeOf<FIXED_INFORMATION>();
                int    returnValue = -1;

                while(returnValue != WIN32Helper.ERROR_SUCCESS)
                {
                    bufferHandle = Marshal.AllocHGlobal(Convert.ToInt32(bufferLength));

                    returnValue = WIN32Helper.GetNetworkParams(bufferHandle, ref bufferLength);

                    if(returnValue == WIN32Helper.ERROR_BUFFER_OVERFLOW)
                    {
                        Marshal.FreeHGlobal(bufferHandle);

                        continue;
                    }
                }

                FIXED_INFORMATION fixedInformation = Marshal.PtrToStructure<FIXED_INFORMATION>(bufferHandle);

                DynamicSystem.DomainName = fixedInformation.DomainName;

                string nodeType = string.Empty;

                switch(fixedInformation.NodeType)
                {
                    case WIN32Helper.BROADCAST_NODETYPE    : nodeType = "Broadcast";                              break;
                    case WIN32Helper.PEER_TO_PEER_NODETYPE : nodeType = "Peer to Peer";                           break;
                    case WIN32Helper.MIXED_NODETYPE        : nodeType = "Mixed";                                  break;
                    case WIN32Helper.HYBRID_NODETYPE       : nodeType = "Hybrid";                                 break;
                    default                                : nodeType = $"Unknown ({fixedInformation.NodeType})"; break;
                }

                DynamicSystem.NodeType = nodeType;
            }
            catch(Exception exception)
            {
                App.WriteLog("MainPage.UpdateSystemData", "GetNetworkParams", exception.Message);
            }

            try
            {
                ConnectionProfile profile = NetworkInformation.GetInternetConnectionProfile();

                DynamicSystem.ConnectedProfile = profile.ProfileName;

                NetworkAdapter internetAdapter = profile.NetworkAdapter;

                DynamicSystem.IANAInterfaceType = $"{(IANAInterfaceType)internetAdapter.IanaInterfaceType}";
                DynamicSystem.InboundSpeed      = $"{internetAdapter.InboundMaxBitsPerSecond  / MBPS:N0} Mbps";
                DynamicSystem.OutboundSpeed     = $"{internetAdapter.OutboundMaxBitsPerSecond / MBPS:N0} Mbps";

                IReadOnlyList<HostName> hostNameList = NetworkInformation.GetHostNames();

                HostName hostName = hostNameList.Where
                (
                    h => h.IPInformation != null &&
                    h.IPInformation.NetworkAdapter != null &&
                    h.IPInformation.NetworkAdapter.NetworkAdapterId == internetAdapter.NetworkAdapterId
                )
                .FirstOrDefault();

                if(hostName != null)
                {
                    DynamicSystem.HostAddress = hostName.CanonicalName;
                    DynamicSystem.AddressType = hostName.Type.ToString();
                }
            }
            catch(Exception exception)
            {
                App.WriteLog("MainPage.UpdateSystemData", "GetInternetConnectionProfile", exception.Message);
            }

            dynamicDataGrid.DataContext = DynamicSystem;
        }
        
        #endregion
        #region 시스템 조회 중단하기 - StopSystemPolling()

        /// <summary>
        /// 시스템 조회 중단하기
        /// </summary>
        private void StopSystemPolling()
        {
            if(this.systemUpdateTimer != null)
            {
                this.systemUpdateTimer.Stop();

                this.systemUpdateTimer = null;
            }
        }

        #endregion

        #region 상세 업데이트하기 - UpdateDetail()

        /// <summary>
        /// 상세 업데이트하기
        /// </summary>
        private void UpdateDetail()
        {
            this.appProcessTask = this.appCollection.GetAppProcesseTask(this.detailApp);

            if(this.appProcessTask != null)
            {
                this.appInformationGrid.DataContext = this.appProcessTask.AppDetail;

                this.resourceGroupTextBlock.Text = $"리소스 그룹 ({this.appProcessTask.AppDetail.GroupDetailList.Count})";

                this.resourceGroupListView.ItemsSource = this.appProcessTask.AppDetail.GroupDetailList;

                this.backgroundTaskTextBlock.Text = $"백그라운드 태스크 ({this.appProcessTask.AppResourceGroupBackgroundTaskReportList.Count})";

                this.backgroundTaskListView.ItemsSource = this.appProcessTask.AppResourceGroupBackgroundTaskReportList;

                this.processDetailTextBlock.Text = $"프로세스 ({this.appProcessTask.ProcessDetailList.Count})";

                this.processDetailListView.ItemsSource = this.appProcessTask.ProcessDetailList;
            }
            else
            {
                this.appInformationGrid.DataContext = null;

                this.resourceGroupTextBlock.Text = "리소스 그룹";

                this.resourceGroupListView.ItemsSource = null;

                this.backgroundTaskTextBlock.Text = "백그라운드 태스크 ";

                this.backgroundTaskListView.ItemsSource = null;

                this.processDetailTextBlock.Text = "프로세스";

                this.processDetailListView.ItemsSource = null;
            }
        }

        #endregion

        #region 정적 시스템 정보 구하기 - GetStaticSystemInformation()

        /// <summary>
        /// 정적 시스템 정보 구하기
        /// </summary>
        private void GetStaticSystemInformation()
        {
           StaticSystem = new StaticSystemModel();

            try
            {
                EasClientDeviceInformation easClientDeviceInformation = new EasClientDeviceInformation();

                StaticSystem.MachineName = easClientDeviceInformation.FriendlyName;
                StaticSystem.MakeModel   = $"{easClientDeviceInformation.SystemManufacturer}, {easClientDeviceInformation.SystemProductName}";
                StaticSystem.FormFactor  = App.DeviceFormFactorType.ToString();

                string deviceFamilyVersion = AnalyticsInfo.VersionInfo.DeviceFamilyVersion;

                ulong v  = ulong.Parse(deviceFamilyVersion);
                ulong v1 = (v & 0xFFFF000000000000L) >> 48;
                ulong v2 = (v & 0x0000FFFF00000000L) >> 32;
                ulong v3 = (v & 0x00000000FFFF0000L) >> 16;
                ulong v4 = (v & 0x000000000000FFFFL);

                string deviceVersion = $"{v1}.{v2}.{v3}.{v4}";

                StaticSystem.OSVersion = deviceVersion;

                SYSTEM_INFORMATION systemInformation = new SYSTEM_INFORMATION();

                WIN32Helper.GetSystemInfo(ref systemInformation);

                StaticSystem.LogicalProcessorCount = systemInformation.ProcessorCount.ToString();
                StaticSystem.Processor             = $"{systemInformation.ProcessorArchitecture}, " +
                                                     $"level {systemInformation.ProcessorLevel}, "  +
                                                     $"rev {systemInformation.ProcessorRevision}";
                StaticSystem.PageSize              = systemInformation.PageSize.ToString();
            }
            catch(Exception exception)
            {
                App.WriteLog("MainPage.GetStaticSystemInformation", "Exception", exception.Message);
            }

            this.staticDataGrid.DataContext = StaticSystem;
        }

        #endregion
    }
}
728x90
그리드형(광고전용)
Posted by icodebroker
,