我有一個進程監視用戶當前正在工作的窗口(GetForegroundWindow)。要獲得HWND的進程ID,我使用GetWindowThreadProcessId。但是,如果前臺應用程序被掛起,我會得到Desktop Window Manager - dwm.exe的進程ID。我可以確定是由IsHungAppWindow掛起的應用程序。 但如何獲得前臺掛起應用程序的真實進程ID?如何獲得沒有響應的前臺應用程序的進程ID?
回答
我們可以使用user32.dll中的未記錄方法HungWindowFromGhostWindow從鬼句柄(如果窗口掛起,dwm創建它的副本)獲取真實的窗口句柄。
namespace HungProcessName
{
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System;
class Program
{
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GhostWindowFromHungWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern IntPtr HungWindowFromGhostWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern bool IsHungAppWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out uint procId);
static void Main(string[] args)
{
while (true)
{
var hwnd = GetForegroundWindow();
Console.WriteLine("Foreground window: {0}", hwnd);
if (IsHungAppWindow(hwnd))
{
var hwndReal = HungWindowFromGhostWindow(hwnd);
uint procId = 0;
GetWindowThreadProcessId(hwndReal, out procId);
if (procId > 0)
{
Process proc = null;
try { proc = Process.GetProcessById((int)procId); }
catch (Exception ex)
{
Console.WriteLine("Could not get proces with Id '{0}': {1}", procId, ex);
}
if (proc != null)
{
Console.WriteLine("Ghost hwnd: {0}, Real hwnd: {1}. ProcessId: {2}, Proccess name: {3}",
hwnd, hwndReal, procId, proc.ProcessName);
}
}
}
Thread.Sleep(100);
}
}
}
}
我們爲什麼要使用這個無證API?你肯定會欣賞風險嗎?你意識到你不應該這樣做?誰說懸掛的窗戶有一扇幽靈窗戶。他們通常不會。進程可以禁用重影。此外窗口可以掛起,不會被幻影,因爲沒有人試圖與它進行交互。 –
@David Heffernan,至少TaskManager [taskmgr.exe] [使用此技術](http://i67.tinypic.com/34dkl6f.png)。我給了測試代碼。在檢查之前,可以使用WM_NULL發送[SendMessageTimeout](https://msdn.microsoft.com/en-us//library/windows/desktop/ms644952(v = vs.85).aspx)。當然,如果有人調用[DisableProcessWindowsGhosting](https://msdn.microsoft.com/en-us/library/ms648415(v = vs.85).aspx),它將無法工作。你有更好的主意嗎? –
好的任務管理器是is shell的一部分。當然,它可以使用私人API調用。你不能。這個問題的問題是我們不知道你爲什麼問。也許你真正的問題有不同的解決方案。 –
那麼使用C#,System.Diagnostics
和System.Linq
你可以這樣做:
List<IntPtr> handles = System.Diagnostics.Process.GetProcesses()
.Where(x => !x.Responding)
.Select(x => x.MainWindowHandle).ToList();
它返回一個不響應的進程的句柄。
它會給出沒有響應應用程序的進程ID。但如何將它與前景窗口進行映射? –
我應該使用Process.MainWindowHandle嗎? –
@ArtavazdBalayan答案已更新。 – user3185569
- 1. 如何獲得前一個應用程序的進程ID
- 2. 如何獲得控制檯的進程id在C#控制檯應用程序
- 3. 如何獲得進程「類型」(應用程序,後臺進程或Windows進程)
- 4. 如何在我的iPad應用程序中應用背景進程而不影響前臺運行的進程?
- 5. VB6:如何獲得程序的句柄ID給予DDE響應
- 6. 有沒有辦法獲得應用程序的當前狀態?
- 7. Windows手機:如何獲得當前應用程序ID
- 8. Laravel如何獲得其他應用程序的響應?
- 9. 在android應用程序中沒有得到url的響應
- 10. 非託管C++獲取當前進程ID? (控制檯應用程序)
- 11. Facebook應用程序進入前臺後
- 12. Glassfish web應用程序沒有響應
- 13. 對Web應用程序沒有響應
- 14. 應用程序沒有響應
- 15. 應用程序沒有響應
- 16. Spring應用程序沒有響應
- 17. XNA應用程序沒有響應
- 18. 應用程序沒有響應
- 19. phonegap android應用程序沒有響應
- 20. 應用程序沒有響應
- 21. 應用程序沒有響應
- 22. DotCloud:應用程序沒有響應
- 23. 如何獲得Android應用程序的應用程序列表?
- 24. 如何獲得已安裝應用程序的進程名稱
- 25. 如何知道你的應用程序沒有響應?
- 26. 程序沒有響應
- 27. gps應用程序的後臺進程
- 28. Facebook應用程序ID獲得一個
- 29. 如何以編程方式識別沒有響應的進程
- 30. 如何獲得應用程序ID和會話ID主人MediaFire
使用'System.Diagnostics.Process'類適合您的選項? – user3185569
@ user3185569,在我的情況下,System.Diagnostics.Process有什麼好處? –
您試圖過濾掉dwm.exe? – Essigwurst