服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - c# 调用Win32Api关闭当前应用的方法

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

2022-11-04 11:49louzi C#

这篇文章主要介绍了c# 调用Win32Api关闭当前应用的方法,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下

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发送关闭窗口信息。

具体实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// 过滤掉系统的一些窗口
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

以上就是c# 调用Win32Api关闭当前应用的方法的详细内容,更多关于c# 调用Win32Api关闭应用的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/louzixl/p/14381984.html

延伸 · 阅读

精彩推荐
  • C#一文说通异步 LINQ

    一文说通异步 LINQ

    早期的 LINQ,主要是同步的,直到 C# 8.0 加入 IAsyncEnumerable,LINQ 才真正转向异步。这本来是个非常好的改变,配合 System.Linq.Async 库提供的扩展,可以在诸如...

    老王Plus6632021-09-15
  • C#C#把UNICODE编码转换为GB编码的实例

    C#把UNICODE编码转换为GB编码的实例

    下面小编就为大家带来一篇C#把UNICODE编码转换为GB编码的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C#教程网10532021-12-22
  • C#C# 打印网页不显示页眉页脚的实现方法

    C# 打印网页不显示页眉页脚的实现方法

    这篇文章主要介绍了C# 打印网页不显示页眉页脚的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    森大科技11202022-08-16
  • C#浅谈C#中的值类型和引用类型

    浅谈C#中的值类型和引用类型

    在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。下面我们来简单谈谈C#中的值类型和引用类型...

    Joye.Net8252021-11-26
  • C#winform实现拖动文件到窗体上的方法

    winform实现拖动文件到窗体上的方法

    这篇文章主要介绍了winform实现拖动文件到窗体上的方法,以实例分析了C#中WinForm操作窗体及文件的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    我心依旧9502021-10-27
  • C#C# winfrom实现读取修改xml

    C# winfrom实现读取修改xml

    这篇文章主要为大家详细介绍了C# winfrom实现读取修改xml的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    wangjingjing101410662021-11-21
  • C#细说C#中的枚举:转换、标志和属性

    细说C#中的枚举:转换、标志和属性

    枚举是 C# 中最有意思的一部分,大部分开发人员只了解其中的一小部分,甚至网上绝大多数的教程也只讲解了枚举的一部分。那么,我将通过这篇文章向大...

    朱钢11532022-08-27
  • C#C# 实现SDL2进行视频播放窗口截图和字幕添加

    C# 实现SDL2进行视频播放窗口截图和字幕添加

    这篇文章主要介绍了C# 实现SDL2进行视频播放窗口截图和字幕添加,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    boonya11102022-10-20