问题
I have a routine that get's all open windows (processes) and then searches for it's classname with the GetClassName method in user32. But when for example Teamviewer is on the classnames of all applications get the teamviewer classname.
Example: Notepad is open and TeamViewer on classname: 'TeamViewer_TitleBarButtonClass' Notepad is open and TeamViewer off classname: 'Notepad'
I looked how this came and found out that Teamviewer puts a control on top of some application windows.
So how can i find the real classname of the applications and not from Teamviewer?
Process[] processes = Process.GetProcesses();
StringBuilder className = new StringBuilder(100);
For (int i = 0; i < processes.Length; i++)
{
if (processes[i].MainWindowHandle != IntPtr.Zero)
{
list.Add(processes[i]);
GetClassName(processes[i].MainWindowHandle, className, className.Capacity);
}
}
回答1:
The heuristic that the Process class uses to guess which window is the "main" window is not perfect. There isn't any way for an app to mark the windows it creates as "this is the main one". So it punts at the best guess: the first window. This certainly can go wrong, you may find a hidden login window for example.
An alternative is to enumerate the threads in the process from Process.Threads, then for each thread to enumerate the windows it owns with EnumThreadWindows(), calling GetClassName() on each. You'll get to see all of the windows that way and should run across the one you are looking for. Using EnumWindows() is an alternative when can't be selective about the process. That also avoids the crash your current code suffers from when it happens to enumerate the "System" process too early.
The best to deal with intrusive software like this "TeamViewer" is to just uninstall it.
来源:https://stackoverflow.com/questions/19135937/user32-getclassname-isnt-correct