仮面's profile宇宙仮面の C# 研究室.Live SpacePhotosBlogListsMore Tools Help

Blog


    July 16

    プロセスモニタ

    どこかで見たことのあるようなものをWPFで作ってみた。

    image

    簡単に作れるだろうと思っていたのだけど、いくつか、ハマり中。

    1.プロセスの情報を取るいいI/Fが見つからない。System.Diagnostics.Process.GetProcesses() だと、プロセッサタイムが取得できないので、しかたなしにWMIでプロセスの情報を取っているのだけれど、結構重くって、CPUパワーが食われまくり。パフォーマンスカウンターを全プロセス分持つのも芸がないし、Win32 SDKを叩くか?? .NETで、いい方法ない?

    2.画面のリサイズもフォントサイズとPolygon の関係をちゃんと考えないといけないので、意外と難しい。

    3.おまけに6角形にレイアウトするのも面倒。誰か、HexaFlowコントロール作ってくれないかな w

    でも、こんな感じで http://uchukamen.com/pmon/publish.htm 意外と見ていて面白い。

    PS. LINQ は偉大だ。もう LINQ 無しでは生きていけない体になってしまった。

    July 15

    Generic Dictionary の foreach

    あまり使わないので忘れないようにメモ

    Dictionary<uint, Process> processDict = new Dictionary<uint, Process>(100);

    foreach (KeyValuePair<uint, Process> val in processDiff)
    {
       Process p = val.Value;
             …
    }

    July 13

    WPF ユーザーコントロール

    <UserControl x:Class="WpfApplication6.Cell"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            >
        <Grid >
        <Polygon Name="Polygon" Margin="5 5 5 5"
        Points="25,0 75, 0 100,43 75,86 25, 86 0 43"
        Stroke="Purple"
        StrokeThickness="2">
                <Polygon.Fill>
                    <SolidColorBrush Color="Red" Opacity="0.8"/>
                </Polygon.Fill>
            </Polygon>

            <Label Name="label1" HorizontalContentAlignment="Center" Margin="6,15,6,0">Label</Label>
            <Label Name="label2" HorizontalContentAlignment="Center" Margin="4,47,8,21" >Label</Label>
        </Grid>

    </UserControl>

    用途は・・・

    Process 情報の取得に関するメモ2

    WMI を使用して Process 情報を取得する際に LINQ を使用しようとすると

    ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
    ManagementObjectCollection queryCollection1 = query1.Get();

    var query = from proc in queryCollection1 select proc;
    foreach (var process in query)
    {
       …
    }

    エラー    1    ソース型 'System.Management.ManagementObjectCollection' のクエリ パターンの実装が見つかりませんでした。'Select' が見つかりません。範囲変数 'proc' の型を明示的に指定してください。    C:\Users\uchukamen\Documents\Visual Studio 2008\Projects\WpfApplication6\WpfApplication6\Window1.xaml.cs    140    38    WpfApplication6

    というエラーになる。

    回避方法は、範囲変数 proc の型を明示的に指定するために、queryCollection1.Cast<ManagementObject>()  としてあげるとうまくいった。うむむむむ・・・

    ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
    ManagementObjectCollection queryCollection1 = query1.Get();

    var query = from proc in queryCollection1.Cast<ManagementObject>() select proc;
    foreach (var process in query)
    {
        Console.WriteLine(process["ProcessId"] + ":");
        Console.WriteLine(process["Name"] + ":");
        Console.WriteLine(process["KernelModeTime"] + ":");
        Console.WriteLine(process["UserModeTime"] + ":");
    }

    ------

    もうちょっと見やすく?すると、IEnumerable<ManagementObject> にキャストしてくれるということ。

    ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
    ManagementObjectCollection queryCollection1 = query1.Get();
    IEnumerable<ManagementObject> procQuery = queryCollection1.Cast<ManagementObject>();

    var procs = from proc in procQuery select proc;

    foreach (var process in procs)
    {
        Console.WriteLine(process["ProcessId"] + ":");
        Console.WriteLine(process["Name"] + ":");
        Console.WriteLine(process["KernelModeTime"] + ":");
        Console.WriteLine(process["UserModeTime"] + ":");
    }

    Process 情報の取得に関するメモ

    Visual Studio 2008 , Vista で、GetProcesses() でプロセス情報を取得する際に、TotalProcessorTime などプロセッサタイムを取得しようとすると、Win32Exception により取得できない。なぜ??

    var query = from proc in System.Diagnostics.Process.GetProcesses()
                orderby proc.Id
                select new
                {
                    Id = proc.Id,
                    processName = proc.ProcessName,
                    TotalProcessorTime = proc.TotalProcessorTime
                };

    foreach (var process in query)
    {
        Console.WriteLine(process.Id + ":");
        Console.WriteLine(process.processName + ":");
        Console.WriteLine(process.TotalProcessorTime + ":");
    }

    -----------------

    WMI を使用すれば、取得可能。

    ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
    ManagementObjectCollection queryCollection1 = query1.Get();

    foreach (ManagementObject mo in queryCollection1)
    {
        Console.WriteLine(mo["ProcessId"] + "\t" + mo["Name"] + "\t" +
            ":\tKernelModeTime=" + mo["KernelModeTime"] +  // in 100 nanosecond units
            ":\tUserModeTime=" + mo["UserModeTime"]);   // in 100 nanosecond units
    }

    July 06

    Visual Studio 2010

    image

    でフローティングを使用すると、

    image

    独立ウィンドウで開けるのがいい感じ。

    Visual Studio 2010 Parallel - Process

    シーケンシャルだと

    var query = from proc in System.Diagnostics.Process.GetProcesses() select proc;
    foreach (var process in query)
    {
        Console.WriteLine(process.Id + " : " + process.ProcessName);
    }

    これがパラレルだと、

    var query = from proc in System.Diagnostics.Process.GetProcesses() select proc;
    Parallel.ForEach(query, process =>
        {
            Console.WriteLine(process.Id + " : " + process.ProcessName);
        }
    );

    処理的には、パラレルでもシーケンシャルでも関係ないので、パラレルで実行しているほうが処理する人の感覚(意図)に近いのかもしれない。

    Visual Studio 2010 Parallel

    Visual Studio 2010 beta を入れてみた。

    image

     

    using System.Threading;
    using System.Diagnostics;

    Stopwatch sw = new Stopwatch();
    sw.Start();
    Parallel.For(0, 10, x =>
        {
            Console.WriteLine(x.ToString() + " : " + Thread.CurrentThread.ManagedThreadId.ToString());
            Thread.Sleep(5000);
        }
    );
    sw.Stop();

    実行結果

    x : ManagedThreadId

    -------------

    0 : 8
    5 : 10
    1 : 11
    6 : 12
    2 : 13
    7 : 14
    3 : 15
    4 : 8
    8 : 10
    9 : 10

    こんなことができてしまうなんて・・・