简体   繁体   中英

Get all processes opened in a certain Desktop

I'm working on an application that creates a new desktop when launched and using a key combo I can move back and forth between the original and the new desktop. At creation time, in the new desktop a new explorer.exe process is started, so the user can start whatever applications he desires.

When the key combo that sends the exit command is detected, the new desktop is closed, and we return to the original one, but all the applications that the user started in the new desktop are still running.

Is there a way to get a handle on all of this processes opened in the new desktop, having a HANDLE for the Window Station and a HDESK handle for the new Desktop?

Thanks to David Heffernan's idea, I was able to find the following solution. Having a HDESK handle for the desktop, I compare it using GetThreadDesktop function with every thread from the system. I'm not sure that it's the most performant solution, I'm open towards suggestions for improvements, but this works just fine:

int main(void)
{
    // Desktop handles
    HDESK currentDesktop = GetsecondDesktop(GetCurrentThreadId());
    HDESK secondDesktop = CreateDesktop(L"secondDesktop", NULL, NULL, 0, GENERIC_ALL, NULL);

    // Start processes in secondDesktop ...

    // Process enumeration
    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;
    EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded);
    cProcesses = cbNeeded / sizeof(DWORD);

    for (i = 0; i < cProcesses; i++)
    {
        if (aProcesses[i] != 0)
        {
            DWORD pThreadId = ListProcessThreads(aProcesses[i]);
            if (GetsecondDesktop(pThreadId) == secondDesktop)
            {
                TerminateProcess(aProcesses[i]);
            }
        }
    }

    return 0;
}

DWORD ListProcessThreads(DWORD dwOwnerPID)
{
    HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
    THREADENTRY32 te32;

    // Take a snapshot of all running threads  
    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (hThreadSnap == INVALID_HANDLE_VALUE)
        return(FALSE);

    // Fill in the size of the structure before using it. 
    te32.dwSize = sizeof(THREADENTRY32);

    // Retrieve information about the first thread,
    // and exit if unsuccessful
    if (!Thread32First(hThreadSnap, &te32))
    {
        CloseHandle(hThreadSnap);     // Must clean up the snapshot object!
        return(FALSE);
    }

    // Now walk the thread list of the system,
    // and display information about each thread
    // associated with the specified process
    do
    {
        if (te32.th32OwnerProcessID == dwOwnerPID)
        {
            return te32.th32ThreadID;
        }
    } while (Thread32Next(hThreadSnap, &te32));

    //  Don't forget to clean up the snapshot object.
    CloseHandle(hThreadSnap);
    return 0;
}

BOOL TerminateProcess(DWORD dwProcessId)
{
    DWORD dwDesiredAccess = PROCESS_TERMINATE;
    BOOL  bInheritHandle = FALSE;
    HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
    if (hProcess == NULL)
        return FALSE;

    UINT uExitCode = 0;
    BOOL result = TerminateProcess(hProcess, uExitCode);
    CloseHandle(hProcess);
    return result;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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