銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

C# で WMI を使って実行中プロセスの一覧とそのオーナーを取得する

とあるC#で書いているツールでプロセスIDからそのプロセスのオーナーを取得する必要が出てきました。自分のプロセスであれば比較的容易に取得できますが、他プロセスの情報となると難しくなります。そこで、WMI .NET を利用してプロセスの一覧とそのオーナーを取得することにしました。

WMI .NET の概要

リンク先にあるように、System.Management 名前空間を参照します。

f:id:tanaka733:20141004210613p:plain

あとはこんな感じで、Win32_Process クラス.aspx)をインスタンス化し、ManagementClass.GetInstances メソッド (System.Management) でプロセス一覧を取得します。

foreach文で変数の型をManagementObject と指定しているのはキャストするためです。ここからプロセスのオーナーを取得するには、ManagementObject.InvokeMethod メソッド (System.Management) を使って GetOwner メソッドを実行します。

GetOwner method of the Win32_Process class (Windows)

あとはこれを「管理者権限」で実行します。管理者権限がないと、自分以外のオーナーは取得できないようです。

さて、最初のプロセスIDを指定してそのオーナーを取得、であればこんな感じでしょうか。

ManagementObjectCollection が非GenericなIEnumerable なのでCast しているのと、ProcessIdがuint型であるのが注意点です。

こんな感じで便利なWMI .NET ですが、制限事項もあるのでご利用の際は注意してください。

.NET Framework の WMI の制限事項

Primary constructors と Declaration expressions は C# の次のバージョンから取り下げられるようです

C# の次のバージョンはRoslynが導入されるとともにいくつかの新機能が追加される予定で、どの機能が追加される見込みなのかはこのページにまとまっています。

.NET Compiler Platform ("Roslyn") - Home

日々更新されていますが、今週 Primary constructors と Declaration expressions という2つの機能が次のバージョンから「取り下げ」られる見込みだと公開されています。

.NET Compiler Platform ("Roslyn") - Changes to the language feature set

サンプルにもある通り、Primary constructors はこんなコードで引数つきコンストラクタでImmutableなフィールド/プロパティを定義しやすくするものです。

class Point(int x, int y) { … }

Declaration expressions はoutパラメーター修飾子つきのメソッドを呼び出す際に、outパラメーターのところで変数宣言を同時に行えるものです。

int.TryParse(s, out var x);

どちらも割と大き目な機能で、次のバージョンでリリースされることを期待していた人も多いのではないでしょうか。

取り下げた理由としては上にリンクを載せた「Changes to the language feature set」に詳しくやり取されています。新機能を入れるとその機能に対応したIDEやDebuggerも必要であり、これが大き目の下げ圧力になっている。そして、コンパイラーそのものの品質を保つことも必要である、と言っています。

また、C# の次のバージョンの最大の目標はRoslynそのもののリリースであり、そのために言語の新機能は見直さないといけないとも言っています。

残念な気持ちもありますが、それだけRoslynのリリースが現実的にせまっていることではないかと思い、期待もしています。また、その代わりと言ってはなんですが、 string interpolationt (日本語で「文字列挿入句」?)という機能の投入を予定しているようです。

"\{p.First} \{p.Last} is \{p.Age} years old."

といったように、文字列リテラルの中に実行時に評価されるC#の式を挿入できる機能です。Rubyなどではおなじみではないでしょうか。

新しいバージョンのC#の機能はまだまだ議論中です。興味ある方は、最初にあげた Language feature status や、 Discussion をたまにチェックしてみると面白いと思います。

IIS の HttpModule で EventSource を使ってデバッグしてみる

突然ですが、IIS にカスタムHTTPモジュールを追加することができます。

チュートリアル : カスタム HTTP モジュールを作成および登録する

が、これ絡みでバグが起きたのでデバッグしようと思ったのですが、割と手段がなくてつらたんでした...

そこで、今回はこれをEventSource クラスによるログ出力を使ってデバッグしてみました。

EventSource クラス (System.Diagnostics.Tracing)

この説明にあるとおり、ETWに書きこむためのクラスになります。ETWについては、以下のエントリがわかりやすく、続きを期待しているところです。

ちなみに、.NET Framework 4.5以降で使えます。そしてなによりのメリットが追加のライブラリが不要なことです。EventSourceクラスは継承してロギング用の専用のクラスを作成して使います。シンプルな例だとこんな感じになります。

あとは、これを使って適当なところにデバッグ処理を書くとETWに書きこんでくれます。

とりあえずprintf デバッグですが、ログのAPIを追加することも可能です。

で、ETWに書きこまれたログを確認するほうほうですが、SLABのOut-of-Processを使って、ConsoleSinkやFlatFileSinkを使う方法もありますし、

PerfView というツールを使う方法もあります。

Download PerfView from Official Microsoft Download Center

意外とEventSourceの使いどころは多そうです。