我想爲我們的Web測試服務器編寫一個實用程序,該服務器會殺死所有具有「始終位於頂部」窗口的進程。我想這是窗口樣式WS_EX_TOPMOST
,但是,我不是100%確定。枚舉所有「始終位於頂部」的窗口
有沒有在C#的方式:
- 列舉這些都是窗口「總在最前面」
- ,並獲取相應的進程?
我想爲我們的Web測試服務器編寫一個實用程序,該服務器會殺死所有具有「始終位於頂部」窗口的進程。我想這是窗口樣式WS_EX_TOPMOST
,但是,我不是100%確定。枚舉所有「始終位於頂部」的窗口
有沒有在C#的方式:
下面是一個工作示例,它查找所有具有最頂層窗口的進程。但要小心:Windows資源管理器始終有一個最上面的窗口,你可能不想想要殺死該進程。
class Program
{
const int WS_EX_TOPMOST = 0x00000008;
const int WS_VISIBLE = 0x10000000;
const int GWL_STYLE = -16;
const int GWL_EXSTYLE = -20;
static void Main(string[] args)
{
var topmostWindowHandles = new ArrayList();
EnumWindows(EnumWindowsCallback, topmostWindowHandles);
var processesToKill = new HashSet<uint>();
foreach (IntPtr hWnd in topmostWindowHandles)
{
uint processId = 0;
GetWindowThreadProcessId(hWnd, out processId);
processesToKill.Add(processId);
}
foreach (uint pid in processesToKill)
{
Process proc = Process.GetProcessById((int)pid);
Console.WriteLine("Killing " + proc.ProcessName);
// kill process, except explorer.exe
}
}
static bool EnumWindowsCallback(IntPtr hWnd, ArrayList lParam)
{
int exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
int style = GetWindowLong(hWnd, GWL_STYLE);
if ((exStyle & WS_EX_TOPMOST) == WS_EX_TOPMOST
&& (style & WS_VISIBLE) == WS_VISIBLE)
{
lParam.Add(hWnd);
}
return true;
}
public delegate bool EnumWindowsProc(IntPtr hwnd, ArrayList lParam);
[DllImport("user32.dll")]
[return:MarshalAs(UnmanagedType.Bool)]
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, ArrayList lParam);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
}
謝謝,太棒了。不過,我想,我錯誤理解了'WS_EX_TOPMOST'。我正在尋找不失焦的窗戶(例如VLC以「始終保持最佳狀態」)。如果關注另一個窗口,大多數由您的方法找到的應用程序不會保持在最前。你偶然知道如何確定那些「永遠在頂部」窗口? – 2014-11-24 13:10:55
我相信'WS_EX_TOPMOST'是正確的。請參閱http://msdn.microsoft.com/en-us/library/windows/desktop/ff700543%28v=vs.85%29.aspx此外,我們可能必須檢查窗口是否可見...我'米看着下一個... – helb 2014-11-24 13:15:03
@ DR我添加了可見窗口的檢查。現在再試一次。 – helb 2014-11-24 13:20:07
這裏是指找到與最上面的主窗口的所有進程的溶液:
class Program
{
static void Main(string[] args)
{
int WS_EX_TOPMOST = 0x00000008;
int GWL_EXSTYLE = -20;
foreach (Process proc in Process.GetProcesses())
{
IntPtr hWnd = proc.MainWindowHandle;
int res = GetWindowLong(hWnd, GWL_EXSTYLE);
if ((res & WS_EX_TOPMOST) == WS_EX_TOPMOST)
{
Console.WriteLine("Topmost window found for process " + proc.ProcessName);
}
}
}
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
}
這僅檢查是否有過程的主窗口是最頂層。我留下這個答案,因爲它可能有助於解決這個特定的問題(找到最頂層的主窗口)。
所以,你想檢查每個進程,看看它是否有一個窗口總是在最前面的標誌? – Vajura 2014-11-24 09:05:28
我寧願更高效,直接的方式。如果Windows不提供這種方式,我想我必須這樣做...... – 2014-11-24 09:09:17
pinvoke EnumWindow並檢查WS_EX_TOPMOST – Maxwe11 2014-11-24 09:13:48