アプリケーションには、デバッグ用の隠し機能なんかも用意します ヒープ使用量の表示とか(・∀・)

引き続きCompact Framework周りの整理中(・ω・)
今週はメモリマップドファイル、byte配列マーシャラみたいな所から始まって、ToolHelpなんかにも浮気をしつつ、GrahpcsExtension、ControlPaintみたいなUI系の下準備をして、SIPやカレンダーみたいなアプリケーション固有コントロールの作成をしてました。


メモリマップドファイルと言えば、4.0からは標準で含まれるようになるハズだけど、Compact Frameworkでもサポートされるのかしら(・∀・)?
あと、byte配列マーシャラはCompact FrameworkではStructLayoutAttributeのあたりが不満なので、リフレクションでクラスメンバとbyte配列の変換を行うためのものデス。
これもCompact Frameworkで改善して欲しい部分(´д`)


っで、今週の小ネタ。
作成するアプリケーションには、デバッグ用の隠し機能を用意していたりするわけですが(`・ω・´)

まあ、気になるのはやはりメモリの使用量とかで。
自プロセスのManagedなものはGC.GetTotalMemory()で取得すれば良いわけですが、併せて他プロセスも含め、ヒープの使用量も知りたいときは、こんなカンジでどぞ(・∀・)ノ

internal static class NativeMethods
{
    internal const int TH32CS_SNAPHEAPLIST = 1;

    internal struct HEAPLIST32
    {
        public uint dwSize;
        public uint th32ProcessID;
        public uint th32HeapID;
        public uint dwFlags;
    }

    internal struct HEAPENTRY32
    {
        public uint dwSize;
        public IntPtr hHandle;
        public uint dwAddress;
        public uint dwBlockSize;
        public uint dwFlags;
        public uint dwLockCount;
        public uint dwResvd;
        public uint th32ProcessID;
        public uint th32HeapID;
    }

    [DllImport( "toolhelp.dll", SetLastError = true )]
    internal static extern IntPtr CreateToolhelp32Snapshot(uint flags, uint processid);
    [DllImport( "toolhelp.dll", SetLastError = true )]
    internal static extern int CloseToolhelp32Snapshot(IntPtr handle);

    [DllImport( "toolhelp.dll" )]
    internal static extern bool Heap32ListFirst(IntPtr hSnapshot, ref HEAPLIST32 lphl);
    [DllImport( "toolhelp.dll" )]
    internal static extern bool Heap32ListNext(IntPtr hSnapshot, ref HEAPLIST32 lphl);
    [DllImport( "toolhelp.dll" )]
    internal static extern bool Heap32First(IntPtr hSnapshot, ref HEAPENTRY32 lphe, uint th32ProcessID, uint th32HeapID);
    [DllImport( "toolhelp.dll" )]
    internal static extern bool Heap32Next(IntPtr hSnapshot, ref HEAPENTRY32 lphe);
}
public static class Heap
{
    public static uint GetHeapUsage(uint processID)
    {
        uint usage = 0;
        IntPtr hSnapshot = NativeMethods.CreateToolhelp32Snapshot( NativeMethods.TH32CS_SNAPHEAPLIST, processID );

        if( hSnapshot != ( IntPtr )(-1) )
        {
            NativeMethods.HEAPLIST32 heaplist = new NativeMethods.HEAPLIST32();

            heaplist.dwSize = (uint)Marshal.SizeOf( heaplist );

            if( NativeMethods.Heap32ListFirst( hSnapshot, ref heaplist ) )
            {
                do
                {
                    NativeMethods.HEAPENTRY32 heapentry = new NativeMethods.HEAPENTRY32();
                    heapentry.dwSize = (uint)Marshal.SizeOf( heapentry );

                    if( NativeMethods.Heap32First( hSnapshot, ref heapentry, heaplist.th32ProcessID, heaplist.th32HeapID ) )
                    {
                        do
                        {
                            usage += heapentry.dwBlockSize;
                        } while( NativeMethods.Heap32Next( hSnapshot, ref heapentry ) );
                    }
                } while( NativeMethods.Heap32ListNext( hSnapshot, ref heaplist ) );
            }

            NativeMethods.CloseToolhelp32Snapshot( hSnapshot );
        }

        return usage;
    }
}

っで、来週も引き続きUI周りの整理と、その後は通信周りの整理を予定(´Д`)