zoukankan      html  css  js  c++  java
  • Win32Api -- 关闭当前应用

    本文介绍Windows系统下使用Win32API获取当前应用并关闭的方法。

    思路
    1. 使用EnumWindows接口枚举当前窗口;
    2. 过滤掉不可用、隐藏、最小化的窗口;
    3. 过滤掉子窗口;
    4. 通过标题、类名过滤掉系统窗口;
    5. 使用PostMessage发送关闭窗口信息。
    具体实现
    // 过滤掉系统的一些窗口
    private static string[] filterTitles = new string[1] { "program manager"};
    private static string[] filterClasses = new string[5] { "shell_traywnd", "workerw", "button", "progman", "windows.ui.core.corewindow"};
    
    private void CloseCurrentApp()
    {
        CallBack sort = new CallBack(EnumCallback);
        EnumWindows(sort, 0);
        return;
    }
    
    private bool EnumCallback(IntPtr hwnd, int lParam)
    {
        string title = GetWindowText(hwnd);
        StringBuilder className = new StringBuilder(256);
        int nRet = GetClassName(hwnd, className, className.Capacity);
        if (nRet == 0)
            className.Append("");
    
        if (!IsWindowVisible(hwnd))
            return true;
    
        if (!IsWindowEnabled(hwnd))
            return true;
    
        if (IsIconic(hwnd))
            return true;
    
        // 过滤掉子窗口
        IntPtr parent = GetParent(hwnd);
        string parentTitle = GetWindowText(parent);
        if (parent != IntPtr.Zero)
        {
            if (IsWindowVisible(parent) && IsWindowEnabled(parent))
                return true;
        }
    
        IntPtr owner = GetWindow(hwnd, GW_OWNER);
        if (owner != IntPtr.Zero)
        {
            if (IsWindowVisible(owner) && IsWindowEnabled(owner))
                return true;
        }
    
        if (!filterTitles.Contains(title.ToLower()) && !filterClasses.Contains(className.ToString().ToLower()))
        {
            PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
            Console.WriteLine("关闭窗口(句柄:{0}, 标题:{1})!", hwnd, title);
    
            #region 获取窗口信息
            int processID = -1;
            long threadID = -1;
            processID = GetWindowThreadProcessId(hwnd, out threadID);
            bool isiconic = IsIconic(hwnd);
            uint gwlStyle = (uint)GetWindowLong(hwnd, GWL_STYLE);
    
            IntPtr hProcess = OpenProcess(ProcessAccessFlags.QueryInformation, false, processID);
            string fullPath = "";
            if (hProcess != IntPtr.Zero)
            {
                int capacity = 1024;
                StringBuilder processName = new StringBuilder(capacity);
                QueryFullProcessImageName(hProcess, 0, processName, ref capacity);
                fullPath = processName.ToString(0, capacity);
                CloseHandle(hProcess);
            }
    
            Console.WriteLine("-------------------窗口info:---------------");
            Console.WriteLine("====标题:{0} 句柄:{1}====", title, hwnd);
            Console.WriteLine("====父窗口标题:{0} 父窗口句柄:{1}====", parentTitle, parent);
            Console.WriteLine("====进程ID:{0} 类名:{1}====", processID, className.ToString());
            Console.WriteLine("====进程名:{0}====", fullPath);
            Console.WriteLine("====isiconic:{0} 样式:{1}====", isiconic, gwlStyle);
            WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
            placement.length = System.Runtime.InteropServices.Marshal.SizeOf(placement);
            GetWindowPlacement(hwnd, ref placement);
            Console.WriteLine("====placement:{0}====", placement.showCmd);
            EnumPropsDelegate prop = new EnumPropsDelegate(EnumPropsProc);
            EnumProps(hwnd, prop);
            #endregion 获取窗口信息
    
            return false;
        }
    
        return true;
    }
    
    private bool EnumPropsProc(IntPtr hwnd, IntPtr lpszString, IntPtr hData)
    {
        string propName = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(lpszString);
        Console.WriteLine("====属性:{0} 数据:{1}====", propName, hData);
        return true;
    }
    
    #region Win32Api
    public const int GWL_STYLE = (-16);
    public const int GWL_EXSTYLE = (-20);
    public const int GW_OWNER = 4;
    public const int WS_EX_TOOLWINDOW = 0x00000080;
    public const int WM_SYSCOMMAND = 0x0112;
    public const int WM_CLOSE = 0x10;
    public const int SC_CLOSE = 0xF060;
    
    public delegate bool CallBack(IntPtr hwnd, int lparam);
    public delegate bool EnumPropsDelegate(IntPtr hwnd, IntPtr lpszString, IntPtr hData);
    
    [DllImport("user32.dll")]
    public static extern int EnumWindows(CallBack x, int y);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    internal static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int GetWindowTextLength(IntPtr hWnd);
    
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder lpClassName, int nMaxCount);
    
    [DllImport("user32.dll")]
    public static extern bool IsWindowVisible(IntPtr hwnd);
    
    [DllImport("user32.dll")]
    public static extern bool IsWindowEnabled(IntPtr hwnd);
    
    [DllImport("user32.dll", EntryPoint = "IsIconic")]
    public static extern bool IsIconic(IntPtr hWnd);
    
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr GetParent(IntPtr hwnd);
    
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr GetWindow(IntPtr hwndParent, int nCmd);
    
    [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
    public static extern long GetWindowLong(IntPtr hwnd, int nIndex);
    
    [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
    public static extern bool PostMessage(IntPtr hwnd, uint Msg, uint wParam, uint lParam);
    
    [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
         CharSet = CharSet.Unicode, ExactSpelling = true,
         CallingConvention = CallingConvention.StdCall)]
    public static extern int GetWindowThreadProcessId(IntPtr hWnd, out long lpdwProcessId);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenProcess(
         ProcessAccessFlags processAccess,
         bool bInheritHandle,
         int processId
    );
    
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool QueryFullProcessImageName([In]IntPtr hProcess, [In]int dwFlags,
        [Out]System.Text.StringBuilder lpExeName, ref int lpdwSize);
    
    [DllImport("coredll.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CloseHandle(IntPtr hObject);
    
    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
    
    [DllImport("user32.dll")]
    public static extern int EnumProps(IntPtr hWnd, EnumPropsDelegate lpEnumFunc);
    
    public struct WINDOWPLACEMENT
    {
        public int length;
        public int flags;
        public int showCmd;
        public System.Drawing.Point ptMinPosition;
        public System.Drawing.Point ptMaxPosition;
        public System.Drawing.Rectangle rcNormalPosition;
    }
    
    [Flags]
    public enum ProcessAccessFlags : uint
    {
        All = 0x001F0FFF,
        Terminate = 0x00000001,
        CreateThread = 0x00000002,
        VirtualMemoryOperation = 0x00000008,
        VirtualMemoryRead = 0x00000010,
        VirtualMemoryWrite = 0x00000020,
        DuplicateHandle = 0x00000040,
        CreateProcess = 0x000000080,
        SetQuota = 0x00000100,
        SetInformation = 0x00000200,
        QueryInformation = 0x00000400,
        QueryLimitedInformation = 0x00001000,
        Synchronize = 0x00100000
    }
    
    public static string GetWindowText(IntPtr hwnd)
    {
        int capacity = GetWindowTextLength(hwnd) * 2;
        System.Text.StringBuilder lpString = new System.Text.StringBuilder(capacity);
        GetWindowText(hwnd, lpString, lpString.Capacity);
        if (lpString.Length > 0)
        {
            return lpString.ToString();
        }
        return string.Empty;
    }
    #endregion Win32Api
    
    转载请注明出处,欢迎交流。
  • 相关阅读:
    Azure PowerShell (7) 使用CSV文件批量设置Virtual Machine Endpoint
    Windows Azure Cloud Service (39) 如何将现有Web应用迁移到Azure PaaS平台
    Azure China (7) 使用WebMetrix将Web Site发布至Azure China
    Microsoft Azure News(4) Azure新D系列虚拟机上线
    Windows Azure Cloud Service (38) 微软IaaS与PaaS比较
    Windows Azure Cloud Service (37) 浅谈Cloud Service
    Azure PowerShell (6) 设置单个Virtual Machine Endpoint
    Azure PowerShell (5) 使用Azure PowerShell创建简单的Azure虚拟机和Linux虚拟机
    功能代码(1)---通过Jquery来处理复选框
    案例1.用Ajax实现用户名的校验
  • 原文地址:https://www.cnblogs.com/louzixl/p/14381984.html
Copyright © 2011-2022 走看看