0

I'm using Enumprocesses( lpidProcess, cb, lpcbNeeded ) to determine running ProcessIds. How do I subset this list to contain only "Applications", those processes that display on the Task Manager Applications tab?

Thanks in advance.

John-L_.
  • 35
  • 9
  • I've determined I can separate out Console and Services (as reported by tasklist) via the following: `BOOL result = ProcessIdToSessionId(ProcessId, &SessionId); if ( (result)&&(SessionId == WTSGetActiveConsoleSessionId()) ) { ` – John-L_. Nov 29 '18 at 21:02
  • this could be helpful [How to get main window handle from process id?](https://stackoverflow.com/a/21767578/7582247). You could probably use that to query for the window title. I'm not sure if non-applications has windows titles. – Ted Lyngmo Nov 29 '18 at 21:22
  • God, I love that people can read between the lines and we don't have anyone screaming, "What OS?" – user4581301 Nov 29 '18 at 21:43
  • 2
    The winapi tag was helpful :-) – Ted Lyngmo Nov 29 '18 at 21:45
  • Services always run in session 0 only. Comparing `(SessionId == WTSGetActiveConsoleSessionId())` is the wrong check to make, especially since you don't really know which session `WTSGetActiveConsoleSessionId()` actually returns. – Remy Lebeau Nov 29 '18 at 21:56
  • 3
    Also, see [How does Task Manager categorize processes as App, Background Process, or Windows Process?](https://blogs.msdn.microsoft.com/oldnewthing/20171219-00/?p=97606) on MSDN. – Remy Lebeau Nov 29 '18 at 21:57
  • The sentence _If the process has a visible window, then Task Manager calls it an "App"_ was really more helpful than most of the other answers I've seen on the topic. – Ted Lyngmo Nov 29 '18 at 22:21

1 Answers1

1

Per How does Task Manager categorize processes as App, Background Process, or Windows Process? on MSDN:

If the process has a visible window, then Task Manager calls it an "App".

If the process is marked as critical, then Task Manager calls it a "Windows Process".

Otherwise, Task Manager calls it a "Background Process".

So, given a process ID, you can check if it has any visible windows by calling EnumWindows(), where the callback function calls GetWindowThreadProcessId() to check if each window belongs to the process, and IsWindowVisible() to check if each window is visible.

For example:

struct myFindInfo
{
    DWORD processID;
    bool found;
};

static BOOL CALLBACK findVisibleWindowProc(HWND hwnd, LPARAM lParam)
{
    myFindInfo *fi = reinterpret_cast<myFindInfo*>(lParam);
    DWORD pid;
    GetWindowThreadProcessId(hwnd, &pid);
    if ((pid == fi->processID) && IsWindowVisible(hwnd))
    {
        fi->found = true;
        return FALSE;
    }
    return TRUE;
}

bool isApplicationProcess(DWORD processID)
{
    findInfo fi;
    fi.processID = processID;
    fi.found = false;
    EnumWindows(&findVisibleWindowProc, reinterpret_cast<LPARAM>(&fi));
    return fi.found;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • What I have done is similar to this, however, I get only the "explorer.exe" processid, (which I don't necessarily want), and not the Application processid's. The above has very effectively weeded out the "other" Console and Services processid's reported by tasklist. – John-L_. Nov 30 '18 at 17:05