Win32Api -- 关闭当前应用
本文介绍Windows系统下使用Win32API获取当前应用并关闭的方法。
思路
- 使用EnumWindows接口枚举当前窗口;
- 过滤掉不可用、隐藏、最小化的窗口;
- 过滤掉子窗口;
- 通过标题、类名过滤掉系统窗口;
- 使用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
Win32Api -- 关闭当前应用的更多相关文章
- Win32API界面库 - Project wheels 工程基础部分完成
离上次发博文过去了好久,先是要忙一个机器人的项目,然后就是部门的事情和考试周复习,然后就到了考试周,趁着复习的间隙,拾起了寒假时候抄的界面库,修掉了从前的bug. bug1 控件显示问题 当初抄这个库 ...
- python通过win32api轻松获取控件的属性值
1.如何利用句柄操作windows窗体 首先,获得窗体的句柄 win32api.FindWindows() 第二,获得窗体中控件的id号,spy++ 第三,根据控件的ID获得控件的句柄(hwnd) ...
- cad.net 利用win32api实现不重复打开dwg路径的文件夹(资源管理器)
这里地址的方法也是可用的,但是net3.5不能使用 为此我选择使用win32api的方式来遍历当前桌面所有资源管理器 /// <summary> /// 不重复打开dwg路径的资源管理器 ...
- cad.net 利用win32api实现一个命令开关参照面板
首先我要判断是否已经打开了参照面板. 然而cad自己没有相关的系统变量.这时我就需要利用到win32api来判断程序是否打开了参照面板了. 首先学习的是 https://blog.csdn.net/b ...
- C#窗口皮肤制作(二):创建窗口库项目以及最小化、最大化、关闭button的实现
非常高兴有朋友关注这篇博客,同一时候也十分抱歉让关注的朋友久等了,隔上一篇博客也有3个月没有更新,主要是因为3月份辞职,4月份初离职到期离开了北京高德,来到了上海张江.眼下新工作也处于熟悉其中,希望大 ...
- 【转】python win32api win32gui win32con 简单操作教程(窗口句柄 发送消息 常用方法 键盘输入)
作者:https://blog.csdn.net/qq_16234613/article/details/79155632 附:https://www.programcreek.com/python/ ...
- win32api win32gui win32con 窗口句柄 发送消息 常用方法
Pywin32是一个Python库,为python提供访问Windows API的扩展,提供了齐全的windows常量.接口.线程以及COM机制等等. 1.通过类名和标题查找窗口句柄,并获得窗口位置和 ...
- Winfrom 桌面弹窗拦截 关闭进程简易程序 源代码下载
***********************2019 2.7更新 v 2.0*************************************************** 程序 源代码 交互 ...
- python win32api 使用小技巧
前些日子,由于需要,用python写了个小插件,通过win32api 访问外部程序的窗口 并且做些小操作. 因为原来对win32api 不怎么熟悉 所以只好求救.群里有个QQ:32034767 唐骁勇 ...
随机推荐
- JavaHomeWorkList
3.17 关键词:剪刀石头布:随机数 1 import java.util.Scanner; 2 public class JSB { 3 public static void main(String ...
- 前n项余数个数和
一:O(n) 计算贡献:前n项中,能被i(1~n)整除的数的个数为(n/i)个,,也就是 i 给前n项中(n/i)个数做了余数 #include<iostream> using names ...
- UVALive 7146
Long long ago there is a strong tribe living on the earth. They always have wars and eonquer others. ...
- 如何用 4 个小时搭建一个新 “Clubhouse” ,引爆声音社交新风口
Clubhouse,基于实时音频技术的声音社交现象级火爆 最近,让硅谷两位顶级 VC 大打出手争相投资的 Clubhouse 火到了国内,甚至在社交圈里 "一码难求",此种火爆程度 ...
- SPI/QSPI通信协议详解和应用
SPi是高速全双工的串行总线,通常应用在通讯速率较高的场合. SS:从设备选择信号线,也称片选信号线 每个从设备都有一个独立的SS信号线,信号线独占主机的一个引脚,及有多少个从设备就有多少个片选信号线 ...
- SSH服务连接
SSH基本概述 SSH是一个安全协议,在进行数据传输时,会对数据包进行加密处理,加密后在进行数据传输.确保了数据传输安全. SSH服务 ssh: secure shell, protocol, 22/ ...
- OpenStack服务默认端口号
在某些部署中,例如已设置限制性防火墙的部署,您可能需要手动配置防火墙以允许OpenStack服务流量. 要手动配置防火墙,您必须允许通过每个OpenStack服务使用的端口的流量.下表列出了每个Ope ...
- OpenStack Train版-12.创建虚拟网络并启动实例(控制节点)
使用VMware虚拟机创建网络可能会有不可预测到的故障,可以通过dashboard界面,管理员创建admin用户的网络环境 1.第一种: 建立公共提供商网络在admin管理员用户下创建 source ...
- 部署 WordPress 和 Wecenter
目录 基本环境部署(LNMP) 安装 Nginx 安装 PHP7.1 安装 Mariadb 安装 NFS 部署 NFS 服务端 部署 NFS 客户端 部署 WordPress 首台服务器 环境部署 数 ...
- K8S(06)web管理方式-dashboard
K8S的web管理方式-dashboard 目录 K8S的web管理方式-dashboard 1 部署dashboard 1.1 获取dashboard镜像 1.1.1 获取1.8.3版本的dsash ...