WinApi.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. using PTMedicalInsurance.Variables;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using System.Windows.Forms;
  12. namespace PTMedicalInsurance.Common
  13. {
  14. class WinApi
  15. {
  16. private bool IsWindowExist(IntPtr handle)
  17. {
  18. return (!(GetWindow(new HandleRef(this, handle), 4) != IntPtr.Zero) && IsWindowVisible(new HandleRef(this, handle)));
  19. }
  20. [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
  21. public static extern IntPtr GetWindow(HandleRef hWnd, int uCmd);
  22. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  23. public static extern bool IsWindowVisible(HandleRef hWnd);
  24. public static IntPtr GetWindowHandle(string name)
  25. {
  26. Process[] procs = Process.GetProcessesByName(name);
  27. if (procs.Length != 0)
  28. {
  29. return procs[0].MainWindowHandle;
  30. }
  31. return IntPtr.Zero;
  32. }
  33. public delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam);
  34. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  35. public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);
  36. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  37. public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId);
  38. public static IntPtr GetWindowsHandle(string WindowName)
  39. {
  40. IntPtr hwnd = IntPtr.Zero;
  41. Process[] procs = Process.GetProcessesByName(WindowName);
  42. if (procs.Length != 0)
  43. {
  44. hwnd = procs[0].MainWindowHandle;
  45. //MessageBox.Show("??" + procs[0].Id.ToString() + "??" + procs[0].MainWindowHandle.ToString());
  46. //Global.writeLog("GetWindowsHandle=>ProcessID:" + procs[0].Id + ",ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString());
  47. //Global.writeLog("GetWindowsHandle=>CurrentProcessID:" + Process.GetCurrentProcess().Id);
  48. }
  49. //Process ps = procs[0];
  50. //Global.writeLog("Start");
  51. //for (int i = 0; i < ps.Threads.Count; i++)
  52. //{
  53. // var thread = ps.Threads[i];
  54. // string str = string.Empty;
  55. // str = str + "标识符(" + i.ToString() + "):"+ thread.Id.ToString() + System.Environment.NewLine;
  56. // //str = str + "标识符:" + thread. + System.Environment.NewLine;
  57. // str = str +"基本优先级:" + thread.BasePriority.ToString() + System.Environment.NewLine;
  58. // str = str +"当前优先级:" + thread.CurrentPriority.ToString() + System.Environment.NewLine;
  59. // str = str +"内存地址:" + thread.StartAddress.ToInt32() + System.Environment.NewLine;
  60. // str = str +"启动时间:" + thread.StartTime.ToString() + System.Environment.NewLine;
  61. // str = str +"使用时间:" + thread.UserProcessorTime.ToString() + System.Environment.NewLine;
  62. // str = str + "当前状态:";
  63. // switch (thread.ThreadState)
  64. // {
  65. // case System.Diagnostics.ThreadState.Initialized:
  66. // str = str +"线程已经初始化但尚未启动";
  67. // break;
  68. // case System.Diagnostics.ThreadState.Ready:
  69. // str = str +"线程准备在下一个可用的处理器上运行";
  70. // break;
  71. // case System.Diagnostics.ThreadState.Running:
  72. // str = str +"当前正在使用处理器";
  73. // break;
  74. // case System.Diagnostics.ThreadState.Standby:
  75. // str = str +"线程将要使用处理器";
  76. // break;
  77. // case System.Diagnostics.ThreadState.Terminated:
  78. // str = str +"线程已完成执行并退出";
  79. // break;
  80. // case System.Diagnostics.ThreadState.Transition:
  81. // str = str +"线程在可以执行钱等待处理器之外的资源";
  82. // break;
  83. // case System.Diagnostics.ThreadState.Unknown:
  84. // str = str +"状态未知";
  85. // break;
  86. // case System.Diagnostics.ThreadState.Wait:
  87. // str = str +"正在等待外围操作完成或者资源释放";
  88. // break;
  89. // default:
  90. // break;
  91. // }
  92. // if (thread.ThreadState == System.Diagnostics.ThreadState.Wait)
  93. // {
  94. // str = str + System.Environment.NewLine +"等待原因:";
  95. // switch (thread.WaitReason)
  96. // {
  97. // case ThreadWaitReason.EventPairHigh:
  98. // str = str +"线程正在等待事件对高";
  99. // break;
  100. // case ThreadWaitReason.EventPairLow:
  101. // str = str +"线程正在等待事件对低";
  102. // break;
  103. // case ThreadWaitReason.ExecutionDelay:
  104. // str = str +"线程执行延迟";
  105. // break;
  106. // case ThreadWaitReason.Executive:
  107. // str = str +"线程正在等待计划程序";
  108. // break;
  109. // case ThreadWaitReason.FreePage:
  110. // str = str +"线程正在等待可用的虚拟内存页";
  111. // break;
  112. // case ThreadWaitReason.LpcReceive:
  113. // str = str +"线程正在等待本地过程调用到达";
  114. // break;
  115. // case ThreadWaitReason.LpcReply:
  116. // str = str +"线程正在等待对本地过程调用的回复到达";
  117. // break;
  118. // case ThreadWaitReason.PageIn:
  119. // str = str +"线程正在等待虚拟内存页到达内存";
  120. // break;
  121. // case ThreadWaitReason.PageOut:
  122. // str = str +"线程正在等待虚拟内存页写入磁盘";
  123. // break;
  124. // case ThreadWaitReason.Suspended:
  125. // str = str +"线程执行暂停";
  126. // break;
  127. // case ThreadWaitReason.SystemAllocation:
  128. // str = str +"线程正在等待系统分配";
  129. // break;
  130. // case ThreadWaitReason.Unknown:
  131. // str = str +"线程因位置原因而等待";
  132. // break;
  133. // case ThreadWaitReason.UserRequest:
  134. // str = str +"线程正在等待用户请求";
  135. // break;
  136. // case ThreadWaitReason.VirtualMemory:
  137. // str = str +"线程正在等待系统分配虚拟内存";
  138. // break;
  139. // default:
  140. // break;
  141. // }
  142. // }
  143. // Global.writeLog("ThreadsInfo:" + procs[0].Id.ToString() + "_" + procs[0].ProcessName, "Count:" + ps.Threads.Count.ToString(), str);
  144. //}
  145. //Global.writeLog("End");
  146. //foreach (Process process in procs)
  147. //{
  148. // if (process.ProcessName.Contains(WindowName))
  149. // {
  150. // MessageBox.Show($"Process_Name = ({process.ProcessName}), Id = {process.Id}");
  151. // }
  152. //}
  153. //return GetCurrentWindowHandle((uint)procs[0].Id);
  154. //Process[] processes = Process.GetProcesses();
  155. //foreach (Process process in processes)
  156. //{
  157. // if (process.ProcessName.Contains(WindowName))
  158. // {
  159. // MessageBox.Show($"ProcessName = ({process.ProcessName}), Id = {process.Id}");
  160. // }
  161. //}
  162. return hwnd;
  163. }
  164. private static Hashtable processWnd = null;
  165. public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);
  166. //static User32API()
  167. //{
  168. // if (processWnd == null)
  169. // {
  170. // processWnd = new Hashtable();
  171. // }
  172. //}
  173. [DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)]
  174. public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);
  175. [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
  176. public static extern IntPtr GetParent(IntPtr hWnd);
  177. [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
  178. public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);
  179. [DllImport("user32.dll", EntryPoint = "IsWindow")]
  180. public static extern bool IsWindow(IntPtr hWnd);
  181. [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
  182. public static extern void SetLastError(uint dwErrCode);
  183. public static IntPtr GetCurrentWindowHandle()
  184. {
  185. IntPtr ptrWnd = IntPtr.Zero;
  186. uint uiPid = (uint)Process.GetCurrentProcess().Id; // 当前进程 ID
  187. object objWnd = processWnd[uiPid];
  188. if (objWnd != null)
  189. {
  190. ptrWnd = (IntPtr)objWnd;
  191. if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd)) // 从缓存中获取句柄
  192. {
  193. return ptrWnd;
  194. }
  195. else
  196. {
  197. ptrWnd = IntPtr.Zero;
  198. }
  199. }
  200. bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
  201. // 枚举窗口返回 false 并且没有错误号时表明获取成功
  202. if (!bResult && Marshal.GetLastWin32Error() == 0)
  203. {
  204. objWnd = processWnd[uiPid];
  205. if (objWnd != null)
  206. {
  207. ptrWnd = (IntPtr)objWnd;
  208. }
  209. }
  210. return ptrWnd;
  211. }
  212. private static bool EnumWindowsProc(IntPtr hwnd, uint lParam)
  213. {
  214. uint uiPid = 0;
  215. if (GetParent(hwnd) == IntPtr.Zero)
  216. {
  217. GetWindowThreadProcessId(hwnd, ref uiPid);
  218. if (uiPid == lParam) // 找到进程对应的主窗口句柄
  219. {
  220. processWnd[uiPid] = hwnd; // 把句柄缓存起来
  221. SetLastError(0); // 设置无错误
  222. return false; // 返回 false 以终止枚举窗口
  223. }
  224. }
  225. return true;
  226. }
  227. public static IntPtr GetCurrentWindowHandle(uint proid)
  228. {
  229. IntPtr ptrWnd = IntPtr.Zero;
  230. uint uiPid = proid;
  231. object objWnd = processWnd[uiPid];
  232. if (objWnd != null)
  233. {
  234. ptrWnd = (IntPtr)objWnd;
  235. if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd)) // 从缓存中获取句柄
  236. {
  237. return ptrWnd;
  238. }
  239. else
  240. {
  241. ptrWnd = IntPtr.Zero;
  242. }
  243. }
  244. bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
  245. // 枚举窗口返回 false 并且没有错误号时表明获取成功
  246. if (!bResult && Marshal.GetLastWin32Error() == 0)
  247. {
  248. objWnd = processWnd[uiPid];
  249. if (objWnd != null)
  250. {
  251. ptrWnd = (IntPtr)objWnd;
  252. }
  253. }
  254. return ptrWnd;
  255. }
  256. }
  257. }