Get threadId of explorer.exe or get threadId by processName - winapi

I'm trying to get the threadId of explorer.exe. I'm not quite sure how to go about doing that. I've looked into win32 apis for functions of appropriate names, but I haven't quite found what I'm looking for.
I know there is a win32 api for GetWindowThreadProcessId(), but this requires a window handle. If there are no explorer.exe windows open, then how can I get a window handle to explorer? I've thought about using GetDesktopWindow(), but I'm not sure if that gets a handle to a window created by explorer or not. Am I going about getting the threadId of explorer.exe the wrong way? Thanks!

Related

Why does Spy++ fail with console windows

I was attempting to verify that messages were being sent to my window using Spy++ (running Windows 7), but I mistakingly tried to spy on a console window that my program was using for debug output. Spy++ promptly notified me that "The specified window cannot be spied upon. Windows will not allow access to the message stream for this window."
While Spy++ does correctly gather other information about the window (e.x. name, style, class name), it cannot process the message queue. Why is this? And, out of morbid curiosity, is there a way to prevent Spy++ from accessing the message queue of my own custom window using the Windows API?
While Spy++ does correctly gather other information about the window (e.x. name, style, class name), it cannot process the message queue. Why is this?
The console window belongs to the CSRSS process, not the CMD.EXE process. CSRSS is a critical system service that is protected and cannot be hooked without special debug privileges.
"When a user-mode process calls a function involving console windows, process/thread creation, or side-by-side support, instead of issuing a system call, the Win32 libraries (kernel32.dll, user32.dll, gdi32.dll) send an inter-process call to the CSRSS process which does most of the actual work without compromising the kernel."
And, out of morbid curiosity, is there a way to prevent Spy++ from accessing the message queue of my own custom window using the Windows API?
Typically, no. Unless you manage to run your window in a protected system process.
So, I discovered this myself recently, I created a console .NET application which launches a process using CMD.EXE and I ran into an issue with some Win32 interop around the keyboard. So I broke out the previously trusty Spy++ utility to see what was happening to find that I was completely unable to monitor the message queue for my application from it.
So as per the op's question:
"Is there a way to prevent Spy++ from accessing the message queue of my own custom window using the Windows API?"
There is a list of restricted windows classes baked into Spy++:
SpyxxHk (presumably it's own hooking class),
#32768 (Context Menu),
#32769 (the Desktop),
ttyGrab ,
ConsoleWindowClass (Command Prompt)
So, if you in any way tie your app to these classes Spy++ will display that block message when attempting to watch their messages, of course this may not prove useful since it only restricts those classes.
Referring to MS documentation:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd373640(v=vs.85).aspx
"For out-of-context events, the event is delivered on the same thread that called SetWinEventHook. In some situations, even if you request WINEVENT_INCONTEXT events, the events will still be delivered out-of-context. These scenarios include events from console windows and events from processes that have a different bit-depth (64 bit versus 32 bits)"
Suggests it is possible to get console window events.

CreateProcess of console app, and get the main window handled

I am trying to write a program what will manage few console windows, my program will be able to CreateProcess() for new console windows, get a window main handle and the use that handle to resize, close, hide, change title etc. But I cannot find a reliable way to get a main window handle. The purpose is to have a tab bar and switch between created console windows with the click on the tab.
I have tried few ways:
1) use windows "cmd.exe" ability to set window title, and then FindWindow("tmp_title"...)
This has a problem, I do not need cmd.exe running, and also I need a processID for the target program not the cmd.exe. Maybe I should use this way but check for children subprocesses?
2) EnumWindows() then CreateProcess() then wait 40 ms, then EnumWindows() again and find the new window.
This is unreliable! I got two new windows sometimes for weird reasons.
3) use GetWindowThreadProcessId() + EnumWindows(). This worked the best on XP, but on win7 the found window seems to be the wrong one, it's GetWindowText() returns "DefaultIME" and hide/show of this window does nothing. So it is obviously a wrong one.
So any idea how to do it reliably and if possible cross-platform (Cross-windows, XP,Vista,7)

Windows service cannot see Shell_TrayWnd

I need to hide the taskbar and start button via a Windows service.
In a console program I can successfully call FindWindow and/or EnumWindows to get the "Shell_TrayWnd" window and then hide it using ShowWindow(hwnd, SW_HIDE).
But when the service performs FindWindow("Shell_TrayWnd", NULL) it returns NULL, and when the service performs EnumWindows it gets an incomplete list which does not include the "Shell_TrayWnd" window.
Can anyone suggest how a service can see the "Shell_TrayWnd" window, or suggest an alternative method for hiding the taskbar and start button (that works in a service)? Thanks.
The correct way to provide a UI (or otherwise interact with UI elements) for a service is to provide a GUI client that runs in the user's context and uses some IPC method (possibly RPC, possibly message-passing) to communicate with the service. UI processing within privileged services is and always has been a security hole.
If you simply want a computer-wise process to kill the taskbar, then a service is neither needed nor helpful. Configure a scheduled task to run at login. Or set the registry to launch a custom shell instead of explorer.exe. You aren't doing anything that requires privilege other than the user's own account.
To avoid blinking a console window, build your program for the WINDOWS subsystem, or use editbin /SUBSYSTEM:WINDOWS to change the flags in the PE header after build is complete.
Unfortunately, there is no way for a service to access windows. It's a (designed) limitation for services.

How does Spy++ construct its process list?

TL;DR - How does the Spy++ tool really construct its process list?
Stage
We have an MFC desktop application (running on Windows XP) that is hanging in that it doesn't react to any user input anymore. It is redrawn when switching to it via alt-tab however. (It does receive WM_SETFOCUS, WM_ACTIVATE, etc. It apparently does not receive any mouse or keyboard messages.)
Since the app is hanging in some limbo, we pulled a few process dumps, but these were of little help so far. Enter:
Spy++
We used Spy++ to find the information I gave above about the window messages this application seems to be processing. We did this by Opening the Windows View and selecting our application Window and in the Messages properties selected Windows of same process and Messages to View : Select All.
However we first tried to view all messages of this process by opening the Processes View of Spy++ and our application is not shown in this process list. Cross checking on another PC where the app is running normally, the process is also normally shown in the processes list of Spy++.
Can anything about the misbehaving app be inferred from the fact that the process is not shown in Spy++'s Process View, but the main window of the app is shown in the Windows View. Why would a process with a main window that is visible not be shown in Spy++'s Processes View?
The process is listed in Task Manager and in the Attach Process Window of Visual Studio 2005. So these tools apparently use a different method to list processes than Spy++ ... ?
The system where the app is currently hanging is a Windows XP SP2 system and we've used the Spy++ Utility that comes with Visual Studio 2005.
The behavior does recur occasionally, but only after the App has been running for several days!
Running Vista or later? Your process is probably elevated and Spy++ is not. Newer versions of Spy++ require elevation. So, try elevating Spy++ explicitly and see if that helps.
Yes, of course things can be inferred from this. Don't take anything I say too seriously in this context, I'd have to go look at the code. But I believe that Spy goes off and looks at the EnumProcesses API. (http://msdn.microsoft.com/en-us/library/ms682629.aspx)
So, if your process isn't showing up there... hrm.
But, what is different between the system where it's working and the one where it's not?
Spy++ requires the following two values in the registry to be disabled (0) to display the processes/threads list AT ALL:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib
HKLM\System\CurrentControlSet\Services\PerfProc\Performance
Disable Performance Counters -> either 0 or not present
Was going insane trying to find out why it refused to display them. It's some kind of bad joke - this debugger requires itself a debugger to get it working! Not that WinDBG would display any meaningful info, MS doesn't even provide a symbol file on their symbol server, pfft.
Anyway, maybe it doesn't display processes that have their performance counters disabled, because I think, this can be set on individual basis, at least for services, like:
HKLM\SYSTEM\CurrentControlSet\Services\.NET CLR Networking\Performance
Disable Performance Counters
So it's basically always a value of the "Performance" subkey. All this stuff is undocumented, it makes use of advapi32.dll functions like "PerfRegQueryValue" and "PerfRegQueryInfoKey"... don't ask me.

How do I provide the "Find Window's Process" feature in Process Explorer (sysinternals)

I'm developing an application for debugging purposes. I want the user to be able to select the process to be debugged using the mouse. Process Explorer does a great job of this with the "Find Window's Process" feature. What I can't figure out is how it does this? Does anyone know the Window's API that provides this functionality?
Thanks, Grant
I haven't tried this, but it should work: Use WindowFromPoint to get the window handle, then use GetWindowThreadProcessId to get the ID of the process that created the window.
Alternatively, you could use EnumWindows to enumerate all top-level windows on the screen, filter them by some criteria (e.g. position) and then use GetWindowThreadProcessId to get the process IDs.
If I understand you correctly you are looking to enumerate all Windows and perform some action when the target Window in question is found. You can do this by enumerating all current windows and then performing some action when the user is over the window in question. You will have to associate that window handle with a process.
This is not a simple task as it requires going through a lot of hoops but it is possible, just have to put all the pieces together.

Resources