using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; namespace Lskj.Util { public enum ShowWindowCommands : int { SW_HIDE = 0, SW_SHOWNORMAL = 1, //用最近的大小和位置显示,激活 SW_NORMAL = 1, SW_SHOWMINIMIZED = 2, SW_SHOWMAXIMIZED = 3, SW_MAXIMIZE = 3, SW_SHOWNOACTIVATE = 4, SW_SHOW = 5, SW_MINIMIZE = 6, SW_SHOWMINNOACTIVE = 7, SW_SHOWNA = 8, SW_RESTORE = 9, SW_SHOWDEFAULT = 10, SW_MAX = 10 } public class NativeMethods { [DllImport("user32.dll")] public static extern IntPtr EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i); public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter); } /// /// 句柄操作静态类 /// public static class HandleHelper { [DllImport("user32.dll")] public static extern int GetDpiForWindow(IntPtr hwnd); [DllImport("shell32.dll")] public static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, ShowWindowCommands nShowCmd); [DllImport("user32.dll", EntryPoint = "SendMessageA")] public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); [DllImport("user32.dll")] public static extern IntPtr EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i); public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter); [DllImport("user32.dll")] public static extern int EnumThreadWindows(int dwThreadId, WndEnumProc lpfn, int lParam); [DllImport("user32.dll")] public static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("shell32.dll")] public static extern int FindExecutable(string lpFile, string lpDirectory, [Out] StringBuilder lpResult); [DllImport("User32.dll", EntryPoint = "SetParent")] public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", EntryPoint = "ShowWindow")] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); [DllImport("user32.dll", SetLastError = true)] public static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, int dwNewLong); public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong) { if (IntPtr.Size == 4) { return SetWindowLongPtr32(hWnd, nIndex, dwNewLong); } return SetWindowLongPtr64(hWnd, nIndex, dwNewLong); } /// /// 枚举窗口时的委托参数 /// /// /// /// public delegate bool WndEnumProc(IntPtr hWnd, int lParam); /// /// 枚举所有窗口 /// /// /// /// [DllImport("user32")] public static extern bool EnumWindows(WndEnumProc lpEnumFunc, int lParam); /// /// 获取窗口的父窗口句柄 /// /// /// [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)] public static extern IntPtr GetParent(IntPtr hWnd); [DllImport("user32")] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32")] public static extern int GetWindowText(IntPtr hWnd, StringBuilder lptrString, int nMaxCount); [DllImport("user32")] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("user32")] public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); [DllImport("user32")] public static extern bool GetWindowRect(IntPtr hWnd, ref LPRECT rect); [StructLayout(LayoutKind.Sequential)] public readonly struct LPRECT { public readonly int Left; public readonly int Top; public readonly int Right; public readonly int Bottom; } public static bool EnumWindow(IntPtr hWnd, IntPtr parameter) { GCHandle gch = GCHandle.FromIntPtr(parameter); var list = gch.Target as List; if (list == null) { throw new InvalidCastException("GCHandle Target could not be cast as List"); } list.Add(hWnd); return true; } /// /// 窗体列表 /// public static List windowList; /// /// 获取 Win32 窗口的一些基本信息。 /// public struct WindowInfo { public IntPtr Hwnd { get; } public string ClassName { get; } public string Title { get; } public bool IsVisible { get; } public Rectangle Bounds { get; } public bool IsMinimized => Bounds.Left == -32000 && Bounds.Top == -32000; public WindowInfo(IntPtr hWnd, string className, string title, bool isVisible, Rectangle bounds) : this() { Hwnd = hWnd; ClassName = className; Title = title; IsVisible = isVisible; Bounds = bounds; } } /// /// 遍历窗口并查找窗口相关WindowInfo信息 /// /// /// public static List FindAllWindows(Predicate match = null) { windowList = new List(); EnumWindows(OnWindowEnum, 0); return windowList.FindAll(match ?? DefaultPredicate); } public static bool OnWindowEnum(IntPtr hWnd, int lparam) { // 仅查找顶层窗口。 if (GetParent(hWnd) == IntPtr.Zero) { // 获取窗口类名。 var lpString = new StringBuilder(512); GetClassName(hWnd, lpString, lpString.Capacity); var className = lpString.ToString(); // 获取窗口标题。 var lptrString = new StringBuilder(512); GetWindowText(hWnd, lptrString, lptrString.Capacity); var title = lptrString.ToString().Trim(); // 获取窗口可见性。 var isVisible = IsWindowVisible(hWnd); // 获取窗口位置和尺寸。 LPRECT rect = default; GetWindowRect(hWnd, ref rect); var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); // 添加到已找到的窗口列表。 windowList.Add(new WindowInfo(hWnd, className, title, isVisible, bounds)); } return true; } public static readonly Predicate DefaultPredicate = x => x.IsVisible && !x.IsMinimized && x.Title.Length > 0; } public class JobControl { public enum JobObjectInfoType { AssociateCompletionPortInformation = 7, BasicLimitInformation = 2, BasicUIRestrictions = 4, EndOfJobTimeInformation = 6, ExtendedLimitInformation = 9, SecurityLimitInformation = 5, GroupInformation = 11 } [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int nLength; public IntPtr lpSecurityDescriptor; public int bInheritHandle; } [StructLayout(LayoutKind.Sequential)] struct JOBOBJECT_BASIC_LIMIT_INFORMATION { public Int64 PerProcessUserTimeLimit; public Int64 PerJobUserTimeLimit; public Int16 LimitFlags; public UInt32 MinimumWorkingSetSize; public UInt32 MaximumWorkingSetSize; public Int16 ActiveProcessLimit; public Int64 Affinity; public Int16 PriorityClass; public Int16 SchedulingClass; } [StructLayout(LayoutKind.Sequential)] struct IO_COUNTERS { public UInt64 ReadOperationCount; public UInt64 WriteOperationCount; public UInt64 OtherOperationCount; public UInt64 ReadTransferCount; public UInt64 WriteTransferCount; public UInt64 OtherTransferCount; } [StructLayout(LayoutKind.Sequential)] struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION { public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; public IO_COUNTERS IoInfo; public UInt32 ProcessMemoryLimit; public UInt32 JobMemoryLimit; public UInt32 PeakProcessMemoryUsed; public UInt32 PeakJobMemoryUsed; } /// /// 创建作业对象 /// /// 该作业的安全描述符 /// 作业名字 /// [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string name); /// /// 将进程注册为作业对象进程 /// /// 作业对象句柄 /// 进程句柄 /// [DllImport("kernel32.dll", SetLastError = true)] static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process); /// /// 设置作业对象限制 /// /// 标识要限制的作业 /// 枚举类型,用于指明要使用的限制类型 /// 包含限制设置值的数据结构的地址 /// 指明第三个参数的大小 /// [DllImport("kernel32.dll")] static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength); const System.String job_name = "Leventure_SeatJob"; private System.UInt32 job_ptr = 0; private System.IntPtr job_handle = System.IntPtr.Zero; /// /// 构造函数,声明作业对象,限制作业对象。 /// public JobControl() { job_handle = CreateJobObject(System.IntPtr.Zero, job_name); JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION(); info.LimitFlags = 0x2000; JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION(); extendedInfo.BasicLimitInformation = info; //Design by LeventureQys int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false); if (!SetInformationJobObject(job_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length)) throw new Exception(string.Format("Unable to set information. Error: {0}", Marshal.GetLastWin32Error())); } /// /// 为该dll注册子进程,当主程序崩溃的时候,子进程一样退出 /// /// /// public bool AddProcess(IntPtr intPtr) { System.IntPtr handle = System.IntPtr.Zero; handle = intPtr; return AssignProcessToJobObject(job_handle, handle); } } }