0

有没有办法获得一个包含所有现有窗口的窗口标题和句柄对的二维数组?

我认为这需要首先获取所有打开的窗口的标题,然后检索它们的句柄并从两个列表构建二维数组,但我不完全确定如何做到这一点。

我也知道它涉及Process.GetProcesses()方法,但我不完全确定如何去做。

4

1 回答 1

2

查看http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx并阅读 MainWindowTitle 和 MainWindowHandle 属性。

GetProcesses 方法为您返回一个正是此类 Process 对象的列表。因此,以详细的形式:

Process[] procs = Process.GetProcesses();
object[,] thearray = new object[procs.Length,2];
for(int i=0;i<procs.Length;++i)
{
    thearray[i,0] = procs[i].MainWindowTitle;
    thearray[i,1] = procs[i].MainWindowHandle;
}

就是这样。现在,如果您想获取第 N 个进程信息:

string title = (string)thearray[n][0];
IntPtr handle = (IntPtr)thearray[n][1];

如您所见,存在数组只有一种数据类型的问题。这意味着保留一个字符串和一个 IntPtr(句柄)会迫使您找到一个通用的超类型,即 .. 最通用的“对象”类型。因此,您必须在读取数据时进行强制转换,因为只有您知道在 [0] 处的对象实际上是一个字符串。

考虑使用 Dictionary 类。这样您就可以很好地输入您的数据 - 但您将失去流程的“顺序”。它们将被随机排序。但我不认为此时您仍然需要订单?请参阅此处的代码:

Process[] procs = Process.GetProcesses();
Dictionary<string, IntPtr> theMap = new Dictionary<string,IntPtr>();
foreach(var p in procs)
    theMap[p.MainWindowTitle] = p.MainWindowHandle;

就是这样。现在,如果您想阅读流程信息:

foreach(var aPair in theMap)
{
    string title = aPair.Key;
    IntPtr handle = aPair.Value;
    ...
}

请注意,使用 Dictionary 访问第 N 个元素有点困难,但通常无论如何您都不需要它。如果您需要它 - 您可以将 LINQ 添加到工具集中:

using System.Linq;

var myNthPair = theMap.ElementAt(n);
string title = myNthPair.Key;
IntPtr handle = myNthPair.Value;

所以,还不错。由于我们手头有 LINQ,我们可以编写更短的初始字典创建代码:

var theMap = Process.GetProcesses().ToDictionary(p => p.MainWindowTitle, p => p.MainWindowHandle);

行。所以让我们解决一件事——我用字典骗了你一点。Dictio 有一个约束:键必须是唯一的。窗口标题可能是任何!他们可能会重复,而且肯定会重复。因此,您必须将键与值交换并形成字典 - 因为句柄不应重复 - 否则您可以使用 LINQ .ToLookup 方法而不是 .ToDictionary。Lookup 为单个键保存多个值,因此对于“Internet Explorer”窗口标题,它将能够保存 15 个句柄的列表等。

玩得开心。

于 2012-08-14T19:20:40.543 回答