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


猜你喜欢
- 引言最近的项目需求中有使用到后端发送http请求,在网上寻找资料后发现可以使用spring自带的RestTemplate类实现,故作此记录项
- 简介本文用示例介绍SpringMVC如何通过JSON格式传递入参。JSON格式使用post方式来请求,即:对应的注解为:@PostMappi
- 利用Java,在控制台操作下,编写的五子棋,作为复习二维数组,面向对象等基础知识。w表示白棋,b表示黑棋import java.util.S
- java 基础之JavaBean属性命名规范问题JavaBean属性名要求:前两个字母要么都大写,要么都小写下面我们来找找如果不遵循这个规范
- SearchView是搜索框组件,它可以让用户在文本框里输入文字,通过 * 取得用户的输入,当用户点击搜索时, * 执行实际的搜索。本文就为
- 前言 SQLite是一种轻量级的小型数据库,虽然比较小,但是功能相对比较完善,一些常见的数据库基本功能也具有,在现在的嵌入式系统中使用该数据
- Kotlin简介Kotlin是一种针对Java 平台的新编程语言。Kotlin简洁、安全、务实,并且专注于与Java代码的互操作性。它几乎可
- 本文实例讲述了Android编程实现的短信编辑器功能。分享给大家供大家参考,具体如下:修改短信数据库,从而生成任意手机号发送的短信。Andr
- 这几天恰好和朋友谈起了递归,忽然发现不少朋友对于“尾递归”的概念比较模糊,网上搜索一番也没有发现讲解地完整详细的资料,于是写了这么一篇文章,
- ThymeleafThymeleaf是最近SpringBoot推荐支持的模板框架,官网在thymeleaf.org这里。我们为什么要用Thy
- 本文实例讲述了Android实现将一个Activity设置成窗口样式的方法。分享给大家供大家参考,具体如下:1.在res/value文件夹下
- 泛型代码可以让你写出根据自我需求定义、适用于任何类型的,灵活且可重用的函数和类型。它可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码
- JVM内存模型在JVM中内存被分成两大块,分别是堆内存和堆外内存,堆内存就是JVM使用的内存,而堆外内存就是非JVM使用的内存,一般是分配给
- 题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。程序分析:利用while语句,条件为输入的字符不为 '\n
- 1、Java序列化与反序列化是什么?Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象
- 前面介绍了Spring Boot 整合mybatis 使用注解的方式实现数据库操作,介绍了如何自动生成注解版的mapper 和pojo类。
- 第一种:(调用系统API)首先引入两个命名空间using System.Runtime.InteropServices;using Syst
- kafka-console-consumer.sh解读kafka-console-consumer.sh 脚本是一个简易的消费者控制台。该
- 1)页面跳转 直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转。 返回带有前缀的字符串:转发:
- 本文接着上一篇,继续为大家分享了JavaWeb实现学生信息管理系统的第二篇,供大家参考,具体内容如下今日任务:实现学生管理系统的查找和添加功