0

forループの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);
    }
  }

} ありがとうございました。

4

1 に答える 1

1

GetProcessesByName渡した名前に一致するプロセスが見つからない場合(リストを確認してください)、空の配列を返し、。First()をスローしInvalidOperationExceptionます。IDを取得する前に、おそらく使用FirstOrDefault()して確認する必要があります。null

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

if (process != null)
{
    foreach (var handle in EnumerateProcessWindowHandles(process.Id))
    {
        // ...
    }
}
// ...
于 2012-07-11T15:12:58.567 に答える