c# 调用Win32Api关闭当前应用的方法
作者:louzi 发布时间:2023-09-22 20:51:26
标签:c#,Win32Api,关闭应用
Win32 API
Win32 API即为Microsoft 32位平台的应用程序编程接口(Application Programming Interface)。所有在Win32平台上运行的应用程序都可以调用这些函数
使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 Microsoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。
在具体编程时,程序实现方式的差异依赖于相应平台的底层功能的不同。最显著的差异是某些函数只能在更强大的平台上实现其功能。例如,安全函数只能在Windows NT操作系统下使用。另外一些主要差别就是系统限制,比如值的范围约束,或函数可管理的项目个数等等。
本文介绍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
来源:https://www.cnblogs.com/louzixl/p/14381984.html
0
投稿
猜你喜欢
- SpringBoot JPA分页查询指定列并返回指定实体用习惯Mybatis,没用过jpa 真是各种踩坑了脑壳疼,一个分页弄老半天,原来就一
- 目标&背景我们以“处理订单数据”为例,假设我们的应用是一个分布式应用,有"订单应用","物流应用&qu
- 1. 启动入口本系列RocketMQ4.8注释github地址,希望对大家有所帮助,要是觉得可以的话麻烦给点一下Star哈前面我们已经分析完
- 目录MotionEventViewViewGroup事件拦截寻找目标视图,分发ACTION_DOWN分发除ACTION_DOWN外的其他事件
- MDC介绍MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 、logback及log4j2 提供的
- 体验了一下美团外卖的底部导航栏,感觉动画很流畅,分割线被顶起,还有图标的动画,可能用的lottie,觉得分割线被顶起可以自己写动画,所以试着
- 打jar包实现分离依赖lib和配置为了业务需要配置文件和jar分离,便于使用者修改配置信息,在网上找了很久,最终找到一个简单有效的方法。操作
- 首先,这两者是完全不同的概念,绝对不能混为一谈。1.什么是Java内存模型?Java内存模型是Java语言在多线程并 * 况下对于共享变量读写
- 1:首先我们看一下数据库的表:这里的pid就是代表他的父节点id,如果没有父节点,那么pid就是0,上面的表就可以看作是一个tree结构,那
- 写在前面在平时的开发之中,我们需要对于数据加载的情况进行展示:空数据网络异常加载中等等情况现在设置页面状态的方式有多种,由于笔者近期一直在使
- 本文实例讲述了C#实现基于Base64的加密解密类。分享给大家供大家参考。具体如下:这个C#类是一个基于Base64的加密和解密类,用户可以
- 一、背景当我们在drools中编写规则时,有些时候存在重复的代码,那么我们是否可以将这些重复代码抽取出来,封装成一个function来调用呢
- RoomRoom主要分三个部分 database、dao和实体类entityEntityentity实体类定义时需要用到@Entity(ta
- Ctrl+1 快速修复Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当
- 本文实例为大家分享了Android RxJava创建操作符Timer的具体代码,供大家参考,具体内容如下之前有写过Android实现倒计时之
- 将DataGrid中上面这个表头变成下面的两行表头,你会怎么实现?很巧妙地截断和补充td tr来实现来源:http://www.cnsend
- 用途项目中使用了 dubbo,注册中心使用的 zookeeper,使用 zookeeper 实现了一个简单的分布式锁(依赖 curator)
- 在C语言中,函数名可以当做函数指针传递给形参从而实现回调void f1() { printf("f1()\n"); }v
- 本文实例为大家分享了C#简单爬虫案例,供大家参考,具体内容如下using System;using System.Collections.G
- 1、背景一般情况下,有些搜索需求是需要根据拼音和中文来搜索的,那么在elasticsearch中是如何来实现基于拼音来搜索的呢?可以通过el