とりあえず、C#のProcessクラスを使ってみる。
(ちなみに、IDEは"Microsoft Visual C# 2008 Express Edition"です)
foreach (Process p in Process.GetProcesses())
{
// ウィンドウを持つプロセスのみをコンソールに表示
if (p.MainWindowHandle != IntPtr.Zero)
{
Console.WriteLine(p.ProcessName + " : " + p.MainWindowTitle);
}
}
これを実行すると、ウィンドウを持つプロセスが全て表示される。
しかし、ウィンドウが非表示のプロセスも表示されてしまう。
さらに、フォルダはエクスプローラが1つだけ表示される。
(元々、エクスプローラにフォルダを読み込んでるだけだから当然と言えば当然)
別の方法でやってみる。今度はWin 32を利用する。
// "DllImport"用に名前空間の修飾省略定義を行う
using System.Runtime.InteropServices;
// コールバックメソッドのデリゲート
private delegate int EnumerateWindowsCallback(IntPtr hWnd, int lParam);
// EnumWindows API関数の宣言
[DllImport("user32.dll", EntryPoint = "EnumWindows")]
private static extern int EnumWindows(EnumerateWindowsCallback lpEnumFunc, int lParam);
// GetWindowText API関数の宣言
[DllImport("user32.dll", EntryPoint = "GetWindowText", CharSet = CharSet.Auto)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCoun//
// IsWindowVisible API関数の宣言
[DllImport("user32.dll", EntryPoint = "IsWindowVisible")]
private static extern int IsWindowVisible(IntPtr hWnd);
// ウィンドウを列挙するためのコールバックメソッド
public static int EnumerateWindows(IntPtr hWnd, int lParam)
{
const int BUFFER_SIZE = 0x1000;
StringBuilder sb = new StringBuilder(BUFFER_SIZE);
// ウィンドウが可視の場合
if (IsWindowVisible(hWnd) != 0)
{
// ウィンドウのキャプションを取得
if (GetWindowText(hWnd, sb, BUFFER_SIZE) != 0)
{
Console.WriteLine(sb);
}
}
// 列挙を継続するには0以外を返す必要がある
return 1;
}
実行は
EnumWindows(new EnumerateWindowsCallback(EnumerateWindows), 0);
と叩くだけ。
これだと、表示されているウィンドウのみが、コンソールに出力される。
(実際に出力されるのは、ウィンドウのタイトル)
"タスク マネージャ"の"アプリケーション"に表示されているものが取得できる。
しかし、今度は"Program Manager"というタイトルのウィンドウも出力される。
こいつは一体なんだ?
色々試してみると、どうやらデスクトップアイコンを管理しているらしい。
他にも何か管理(Managerだからね)してるかもしれない。
まとめると、
ウィンドウの表示・非表示に関わらず、取得したい場合はC#で。
ウィンドウが表示されているもののみを取得したい場合はWin32で。
2種類の方法は状況に応じて使い分けると良さそうだ。(もしくは混合する)
参照:smdn/プログラミングとか趣味のいろいろ
0 件のコメント:
コメントを投稿