基于C#實(shí)現(xiàn)獲取Windows所有窗口句柄
寫在前面
在做錄屏或截屏操作時,需要獲取當(dāng)前正在運(yùn)行中的桌面程序句柄,在網(wǎng)上查找資源的的時候,發(fā)現(xiàn)了一個工具類還不錯,這邊做個驗(yàn)證記錄。
參考代碼
public class WindowApi
{
//尋找目標(biāo)進(jìn)程窗口
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//設(shè)置進(jìn)程窗口到最前
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
#region GetWindowCapture的dll引用
[DllImport("user32.dll")]
private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rectangle rect);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleDC(
IntPtr hdc // handle to DC
);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleBitmap(
IntPtr hdc, // handle to DC
int nWidth, // width of bitmap, in pixels
int nHeight // height of bitmap, in pixels
);
[DllImport("gdi32.dll")]
private static extern IntPtr SelectObject(
IntPtr hdc, // handle to DC
IntPtr hgdiobj // handle to object
);
[DllImport("gdi32.dll")]
private static extern int DeleteDC(
IntPtr hdc // handle to DC
);
[DllImport("user32.dll")]
private static extern bool PrintWindow(
IntPtr hwnd, // Window to copy,Handle to the window that will be copied.
IntPtr hdcBlt, // HDC to print into,Handle to the device context.
UInt32 nFlags // Optional flags,Specifies the drawing options. It can be one of the following values.
);
[DllImport("user32.dll")]
private static extern IntPtr GetWindowDC(
IntPtr hwnd
);
#endregion
/// <summary>
/// 根據(jù)句柄獲取截圖
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
public static Bitmap GetWindowCapture(IntPtr hWnd)
{
IntPtr hscrdc = GetWindowDC(hWnd);
Rectangle windowRect = new Rectangle();
GetWindowRect(hWnd, ref windowRect);
int width = Math.Abs(windowRect.X - windowRect.Width);
int height = Math.Abs(windowRect.Y - windowRect.Height);
IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, width, height);
IntPtr hmemdc = CreateCompatibleDC(hscrdc);
SelectObject(hmemdc, hbitmap);
PrintWindow(hWnd, hmemdc, 0);
Bitmap bmp = Image.FromHbitmap(hbitmap);
DeleteDC(hscrdc);//刪除用過的對象
DeleteDC(hmemdc);//刪除用過的對象
return bmp;
}
/// <summary>
/// 根據(jù)句柄獲取截圖路徑
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
public static string GetCapturePath(IntPtr hWnd)
{
string path = string.Empty;
string dicPath = AppDomain.CurrentDomain.BaseDirectory + "Intercept";
if (!Directory.Exists(dicPath))
{
Directory.CreateDirectory(dicPath);
}
using (Bitmap bitmap = GetWindowCapture(hWnd))
{
path = dicPath + "\\" + Guid.NewGuid().ToString().Replace("-", "") + ".png";
bitmap.Save(path);
}
return path;
}
private delegate bool WNDENUMPROC(IntPtr hWnd, int lParam);
//用來遍歷所有窗口
[DllImport("user32.dll")]
private static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);
//獲取窗口Text
[DllImport("user32.dll")]
private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
//獲取窗口類名
[DllImport("user32.dll")]
private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
//自定義一個結(jié)構(gòu),用來保存句柄信息
public struct WindowInfo
{
public IntPtr hWnd;
public string szWindowName;
public string szClassName;
}
public static WindowInfo[] GetAllDesktopWindows()
{
//用來保存窗口對象 列表
List<WindowInfo> wndList = new List<WindowInfo>();
//enum all desktop windows
EnumWindows(delegate (IntPtr hWnd, int lParam)
{
WindowInfo wnd = new WindowInfo();
StringBuilder sb = new StringBuilder(256);
//get hwnd
wnd.hWnd = hWnd;
//get window name
GetWindowTextW(hWnd, sb, sb.Capacity);
wnd.szWindowName = sb.ToString();
//get window class
GetClassNameW(hWnd, sb, sb.Capacity);
wnd.szClassName = sb.ToString();
//add it into list
wndList.Add(wnd);
return true;
}, 0);
return wndList.ToArray();
}
[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
/// <summary>
/// 釋放內(nèi)存
/// </summary>
public async static Task ClearMemory()
{
//獲得當(dāng)前工作進(jìn)程
Process proc = Process.GetCurrentProcess();
long usedMemory = proc.PrivateMemorySize64;
if (usedMemory > 1024 * 1024 * 10)
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
}
await Task.Delay(10);
}
}
}調(diào)用結(jié)果

調(diào)用示意:
var programList = WindowApi.GetAllDesktopWindows().Where(x => !string.IsNullOrEmpty(x.szWindowName)).ToList();
listBoxWindows.DataSource = programList.Select(x => x.szWindowName).ToList();
以上就是基于C#實(shí)現(xiàn)獲取Windows所有窗口句柄的詳細(xì)內(nèi)容,更多關(guān)于C#獲取Windows窗口句柄的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#和SQL實(shí)現(xiàn)的字符串相似度計(jì)算代碼分享
這篇文章主要介紹了C#和SQL實(shí)現(xiàn)的字符串相似度計(jì)算代碼分享,本文分別給出了C#語言和SQL語言的實(shí)現(xiàn)代碼,需要的朋友可以參考下2014-10-10
C# ThreadPool之QueueUserWorkItem使用案例詳解
這篇文章主要介紹了C# ThreadPool之QueueUserWorkItem使用案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
C#之App.Config文件操作的實(shí)現(xiàn)
AppConfigHelper提供了一種方便的方式來讀取、添加、修改和刪除應(yīng)用程序配置文件中的配置項(xiàng),本文主要介紹了C#之App.Config文件操作的實(shí)現(xiàn),感興趣的可以了解一下2026-01-01
C#之System.Threading.Lock與lock使用及區(qū)別
本文詳細(xì)比較了C#中傳統(tǒng)lock語句與System.Threading.Lock的異同,涵蓋語法復(fù)雜度、異常處理、超時控制及性能影響等方面,幫助開發(fā)者選擇合適的同步機(jī)制2026-05-05

