c# 调用Win32Api关闭当前应用的方法

作者:louzi 时间:2023-09-22 20:51:26 

Win32 API

Win32 API即为Microsoft 32位平台的应用程序编程接口(Application Programming Interface)。所有在Win32平台上运行的应用程序都可以调用这些函数

  • 使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 Microsoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。

  • 在具体编程时,程序实现方式的差异依赖于相应平台的底层功能的不同。最显著的差异是某些函数只能在更强大的平台上实现其功能。例如,安全函数只能在Windows NT操作系统下使用。另外一些主要差别就是系统限制,比如值的范围约束,或函数可管理的项目个数等等。

本文介绍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

来源:https://www.cnblogs.com/louzixl/p/14381984.html

标签:c#,Win32Api,关闭应用
0
投稿

猜你喜欢

  • C++内存池的简单实现

    2022-05-27 05:20:50
  • Java抽象类和接口使用梳理

    2022-10-02 08:38:46
  • Java设计模式之状态模式State Pattern详解

    2023-11-07 07:55:01
  • 一文彻底搞懂Java和JDK的版本命名问题

    2023-11-24 01:39:25
  • Mybatis如何使用ognl表达式实现动态sql

    2021-06-22 03:34:49
  • android编程实现对话框的封装实例

    2022-02-12 12:58:54
  • EventBus与Spring Event区别详解(EventBus 事件机制,Spring Event事件机制)

    2023-12-06 00:23:05
  • C#先判断是否存在再创建文件夹或文件与递归计算文件夹大小

    2023-07-29 00:04:58
  • Java 的 FileFilter文件过滤与readline读行操作实例代码

    2022-04-09 07:22:53
  • Java编程之内置观察者模式实例详解

    2021-07-02 20:43:27
  • 解析Android中webview和js之间的交互

    2023-07-27 17:16:50
  • 浅谈抛出异常和捕获异常的一些区别

    2023-10-19 15:25:24
  • Android内置SQLite的使用详细介绍

    2021-10-24 11:44:17
  • C#实现基于IE内核的简单浏览器完整实例

    2021-12-04 02:08:02
  • Unity 按钮添加OnClick事件操作

    2023-06-28 15:57:27
  • C#用递归算法实现:一列数的规则如下: 1、1、2、3、5、8、13、21、34,求第30位数是多少

    2023-12-23 01:22:51
  • Android View与Compose互相调用实例探究

    2021-06-11 09:07:29
  • Android studio 快速删除无用资源的方法

    2022-10-06 20:53:42
  • Spring中使用atomikos+druid实现经典分布式事务的方法

    2023-07-14 00:46:17
  • 两分钟解决IntelliJ IDEA中文乱码问题(推荐)

    2022-11-09 00:08:15
  • asp之家 软件编程 m.aspxhome.com