10

I'm trying to find a way to get the open tasks in C#. I've been searching on google and can only find how to get a list of the processes. I want the only the tasks that would show up on the taskbar.

Also, along with that, it would be cool if I could get the process the task is associated with. And if possible get the thumbnail images that Vista uses for the ALT-TAB menu, like in this image:

alt-tab

I assume that I will have to use pinvokes because it really doesn't look like there are any libraries to do this already. Any ideas?

Adaline Simonian
  • 4,596
  • 2
  • 24
  • 35
Joel
  • 16,474
  • 17
  • 72
  • 93

4 Answers4

5

From an API (Win32) perspective there is no such thing as Tasks (at least not the one that Windows Task Manager/Alt-Tab shows).

Those "Tasks" are actually top level windows.

So in order to get a list of those, you need to enumerate the windows (here is the PInvoke for it).

Then look at the style of the windows to determine if they are actually top level windows.

Asher
  • 1,867
  • 15
  • 24
5

This article should pretty much tell you exactly what to do, it shows how to build your own task switch and includes the code needed to enumerate all windows and determine if they are "tasks" and it shows you how to use PrintWindow api to get the previews on XP.

http://msdn.microsoft.com/en-us/library/ms997649.aspx

Also, here is a blog post that talks about the algorithm used to determine what shows up in the Alt+Tab view. Basically you need to check the WS_EX_APPWINDOW and WS_EX_TOOLWINDOW along with if the window has an owner.

Maurice Flanagan
  • 5,179
  • 3
  • 30
  • 37
1

I haven't tried it, but I suspect something like this:

using System.Diagnostics;
static void MyFunc()
{
    Process[] processes = Process.GetProcesses();
    foreach(Process p in processes)
    {
       if (p.MainWindowHandle != 0)
       { // This is a GUI process
       }
       else
       { // this is a non-GUI / invisible process
       }
    }
}

The point is to check each process for a WindowHandle.

abelenky
  • 63,815
  • 23
  • 109
  • 159
  • 1
    "If (p.MainWindowHandle != 0)" errors, but "If (p.MainWindowTitle != '')" works, even if it is a bit of a hack. – James Sulak Sep 07 '09 at 03:30
0

@abelenky17

I suspect that this will not cover all cases, for example there are processes who have several top level windows (that all appear in the task manager). Consider for example: FireFox, Windows Explorer, IE, etc... those applications can have multiple windows on the desktop. Also, it will not handle Terminal Sessions scenario's properly (because you enumerate all the processes running in the system).

@Dan C.

Doing something like this:

p.ProcessName != "explorer"

seems ok to you? It smells, bad.

Kay Zed
  • 1,304
  • 2
  • 21
  • 31
Asher
  • 1,867
  • 15
  • 24
  • Smelling as it is, I'd like to see the alternatives :) – Dan C. Nov 22 '08 at 00:16
  • Agreed. The purpose of answering a question is not to cover all cases, or make code that smells "rosy", but to answer the question: that is, provide enough of the missing information that the original questioner can flush out the details. – abelenky Nov 22 '08 at 00:20
  • 1
    Correct. Coming back to the question, I've checked and you're right about firefox not spawning a new process for new instances. So if each separate window of the same application is needed, then the only option is to enumerate windows. – Dan C. Nov 22 '08 at 00:30