我正在尝试将进程名称作为for循环中listBox的字符串,并搜索这些应用程序的所有窗口。当我手动将项目添加到listBox时,它工作正常;但是当我使用嵌入的文本文件来存储和加载进程名称到listBox时,它会搜索所有项目,但只查找最后一项。对于其他的,Process.GetProcessesByName()抛出异常:Sequence不包含任何元素。
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processId)
{
var handles = new List<IntPtr>();
foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
return handles;
}
搜索算法:
public void searchForApplications()
{
for (int i = 0; i < listBox1.Items.Count; i++)
{
try
{
foreach (var handle in EnumerateProcessWindowHandles
(Process.GetProcessesByName(listBox1.Items[i].ToString()).First().Id))
{
StringBuilder message = new StringBuilder(1000);
SendMessage(handle, WM_GETTEXT, message.Capacity, message);
if (message.ToString().Length > 0)
{
addNewApplication(new Applications(message.ToString(), message.ToString(),
int.Parse(handle.ToString())));
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
} 谢谢。
答案 0 :(得分:1)
如果GetProcessesByName
找不到与您传入的名称相匹配的任何进程(请检查您的列表),那么它将返回一个空数组,First()
将抛出InvalidOperationException
。您应该使用FirstOrDefault()
并在获取ID之前检查null
:
// ...
var process = Process.GetProcessesByName(listBox1.Items[i].ToString()).FirstOrDefault();
if (process != null)
{
foreach (var handle in EnumerateProcessWindowHandles(process.Id))
{
// ...
}
}
// ...