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.