简体   繁体   English

EnumWindows无法正常工作

[英]EnumWindows doesn't work properly

I'm trying to take process names as a string from a listBox in a for loop and search for all windows of those applications. 我试图将进程名称作为一个字符串从for循环中的listBox中提取出来,并搜索那些应用程序的所有窗口。 When I add items manually to the listBox, it works fine; 当我手动将项目添加到listBox时,它可以正常工作; but when I use an embedded text file to store and load process names to the listBox, it searches for all items but finds only the last one. 但是,当我使用嵌入式文本文件存储进程名称并将其加载到listBox时,它将搜索所有项,但仅找到最后一项。 For the other ones, Process.GetProcessesByName() throws an exception: Sequence contains no elements. 对于其他情况,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;
}

Searching algorithm: 搜索算法:

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);
    }
  }

} Thank you. } 谢谢。

If GetProcessesByName doesn't find any processes matching the name you passed in (check your list), then it will return an empty array and First() will throw an InvalidOperationException . 如果GetProcessesByName没有找到与您传入的名称匹配的任何进程(请检查您的列表),则它将返回一个空数组,并且First()将引发InvalidOperationException You should probably use FirstOrDefault() and check for null before getting the Id: 您可能应该使用FirstOrDefault()并在获取ID之前检查null

// ...
var process = Process.GetProcessesByName(listBox1.Items[i].ToString()).FirstOrDefault();

if (process != null)
{
    foreach (var handle in EnumerateProcessWindowHandles(process.Id))
    {
        // ...
    }
}
// ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM