My Project
EnumProcess.hpp
1 #pragma once
2 // MSDN Magazine -- July 2002
4 // If this code works, it was written by Paul DiLascia.
5 // If not, I don't know who wrote it.
6 // Compiles with Visual Studio 6.0 and Visual Studio .NET
7 // Runs in Windows XP and probably Windows 2000 too.
8 //
9 
10 #include <stdio.h>
11 #include <tchar.h>
12 #include <string>
13 #include <malloc.h>
14 #include <crtdbg.h>
15 
16 #include <Windows.h>
17 #include <psapi.h>
18 
19 namespace ParaEngine
20 {
22  // Iterate the top-level windows. Encapsulates ::EnumWindows.
23  //
25  protected:
26  HWND* m_hwnds; // array of hwnds for this PID
27  DWORD m_nAlloc; // size of array
28  DWORD m_count; // number of HWNDs found
29  DWORD m_current; // current HWND
30 
31  static BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lp){
32  return ((CWindowIterator*)lp)->OnEnumProc(hwnd);
33  }
34 
35  // virtual enumerator
36  virtual BOOL OnEnumProc(HWND hwnd){
37  if (OnWindow(hwnd)) {
38  if (m_count < m_nAlloc)
39  m_hwnds[m_count++] = hwnd;
40  }
41  return TRUE; // keep looking
42  }
43 
44  // override to filter different kinds of windows
45  virtual BOOL OnWindow(HWND hwnd) {
46  return TRUE;
47  }
48 
49  public:
50  CWindowIterator(DWORD nAlloc=1024)
51  {
52  //ASSERT(nAlloc>0);
53  m_current = m_count = 0;
54  m_hwnds = new HWND [nAlloc];
55  m_nAlloc = nAlloc;
56  }
57 
59  {
60  delete [] m_hwnds;
61  }
62 
63  DWORD GetCount() { return m_count; }
64  HWND First(){
65  ::EnumWindows(EnumProc, (LPARAM)this);
66  m_current = 0;
67  return Next();
68  }
69  HWND Next() {
70  return m_hwnds && m_current < m_count ? m_hwnds[m_current++] : NULL;
71  }
72  };
73 
75  // Iterate the top-level windows in a process.
76  //
78  protected:
79  DWORD m_pid; // process id
80  virtual BOOL OnWindow(HWND hwnd){
81  if (GetWindowLong(hwnd,GWL_STYLE) & WS_VISIBLE) {
82  DWORD pidwin;
83  GetWindowThreadProcessId(hwnd, &pidwin);
84  if (pidwin==m_pid)
85  return TRUE;
86  }
87  return FALSE;
88  }
89  public:
90  CMainWindowIterator(DWORD pid, DWORD nAlloc=1024){
91  m_pid = pid;
92  }
94  };
95 
97  // Process iterator -- iterator over all system processes
98  // Always skips the first (IDLE) process with PID=0.
99  //
101  protected:
102  DWORD* m_pids; // array of procssor IDs
103  DWORD m_count; // size of array
104  DWORD m_current; // next array item
105  public:
107  m_pids = NULL;
108  }
110  {
111  delete [] m_pids;
112  }
113 
114 
115  DWORD GetCount() { return m_count; }
116  DWORD First(){
117  m_current = (DWORD)-1;
118  m_count = 0;
119  DWORD nalloc = 1024;
120  do {
121  delete [] m_pids;
122  m_pids = new DWORD [nalloc];
123  if (EnumProcesses(m_pids, nalloc*sizeof(DWORD), &m_count)) {
124  m_count /= sizeof(DWORD);
125  m_current = 1; // important: skip IDLE process with pid=0.
126  }
127  } while (nalloc <= m_count);
128 
129  return Next();
130  }
131  DWORD Next() {
132  return m_pids && m_current < m_count ? m_pids[m_current++] : 0;
133  }
134  };
135 
136 
137 
139  // Iterate the modules in a process. Note that the first module is the
140  // main EXE that started the process.
141  //
143  protected:
144  HANDLE m_hProcess; // process handle
145  HMODULE* m_hModules; // array of module handles
146  DWORD m_count; // size of array
147  DWORD m_current; // next module handle
148  public:
149  CProcessModuleIterator(DWORD pid)
150  {
151  // open the process
152  m_hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
153  FALSE, pid);
154  }
155 
157  {
158  CloseHandle(m_hProcess);
159  delete [] m_hModules;
160  }
161 
162  HANDLE GetProcessHandle() { return m_hProcess; }
163  DWORD GetCount() { return m_count; }
164  HMODULE First()
165  {
166  m_count = 0;
167  m_current = (DWORD)-1;
168  m_hModules = NULL;
169  if (m_hProcess) {
170  DWORD nalloc = 1024;
171  do {
172  delete [] m_hModules;
173  m_hModules = new HMODULE [nalloc];
174  if (EnumProcessModules(m_hProcess, m_hModules,
175  nalloc*sizeof(DWORD), &m_count)) {
176  m_count /= sizeof(HMODULE);
177  m_current = 0;
178  }
179  } while (nalloc <= m_count);
180  }
181  return Next();
182  }
183  HMODULE Next() {
184  return m_hProcess && m_current < m_count ? m_hModules[m_current++] : 0;
185  }
186  };
187 
189  // Handy class to facilitate finding and killing a process by name.
191  {
192  public:
193  CFindKillProcess(){}
194  ~CFindKillProcess(){}
195  DWORD FindProcess(LPCTSTR modname, BOOL bAddExe=TRUE, BOOL bSkipCurrentProcess = TRUE)
196  {
197  DWORD dwCurrentPID = GetCurrentProcessId();
198  CProcessIterator itp;
199  for (DWORD pid=itp.First(); pid; pid=itp.Next()) {
200  TCHAR name[_MAX_PATH];
201  CProcessModuleIterator itm(pid);
202  HMODULE hModule = itm.First(); // .EXE
203  if (hModule && (dwCurrentPID != pid || !bSkipCurrentProcess) )
204  {
205  GetModuleBaseName(itm.GetProcessHandle(),
206  hModule, name, _MAX_PATH);
207 
208  std::string sModName = modname;
209  if (_strcmpi(sModName.c_str(),name)==0)
210  return pid;
211  sModName += ".exe";
212  if (bAddExe && _strcmpi(sModName.c_str(),name)==0)
213  return pid;
214  }
215  }
216  return 0;
217  }
218 
219  bool FindAndKillProcess(LPCTSTR modname, BOOL bAddExe=TRUE, BOOL bSkipCurrentProcess = TRUE)
220  {
221  DWORD dwCurrentPID = GetCurrentProcessId();
222  CProcessIterator itp;
223  for (DWORD pid=itp.First(); pid; pid=itp.Next()) {
224  TCHAR name[_MAX_PATH];
225  CProcessModuleIterator itm(pid);
226  HMODULE hModule = itm.First(); // .EXE
227  if (hModule && (dwCurrentPID != pid || !bSkipCurrentProcess))
228  {
229  GetModuleBaseName(itm.GetProcessHandle(),
230  hModule, name, _MAX_PATH);
231 
232  std::string sModName = modname;
233  if (_strcmpi(sModName.c_str(),name)==0)
234  {
235  if(!KillProcess(pid,true))
236  {
237  return false;
238  }
239  }
240  sModName += ".exe";
241  if (bAddExe && _strcmpi(sModName.c_str(),name)==0)
242  {
243  if(!KillProcess(pid,true))
244  {
245  return false;
246  }
247  }
248  }
249  }
250  return true;
251  }
252  BOOL KillProcess(DWORD pid, BOOL bZap){
253  CMainWindowIterator itw(pid);
254  for (HWND hwnd=itw.First(); hwnd; hwnd=itw.Next()) {
255  DWORD_PTR bOKToKill = FALSE;
256  SendMessageTimeout(hwnd, WM_QUERYENDSESSION, 0, 0,
257  SMTO_ABORTIFHUNG|SMTO_NOTIMEOUTIFNOTHUNG, 5000, &bOKToKill);
258  if (!bOKToKill)
259  {
260  printf("program do not exit!");
261  break;
262  }
263  PostMessage(hwnd, WM_CLOSE, 0, 0);
264  }
265 
266  BOOL bKilled = TRUE;
267  HANDLE hp=OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE,FALSE,pid);
268  if (hp) {
269  if (WaitForSingleObject(hp, 5000) != WAIT_OBJECT_0) {
270  if (bZap) {
271  OutputDebugStringA("Terminate Process normally!");
272  TerminateProcess(hp,0);
273  } else {
274  OutputDebugStringA("bzap is false!");
275  bKilled = FALSE;
276  }
277  }
278  else
279  {
280  Sleep(1000);
281  OutputDebugStringA("wait single object return false");
282  if (bZap) {
283  OutputDebugStringA("Terminate Process!");
284  TerminateProcess(hp,0);
285  }
286  }
287  CloseHandle(hp);
288  }
289  else
290  {
291  OutputDebugStringA("hp is null");
292  }
293  return bKilled;
294  }
295  };
296 }
Definition: EnumProcess.hpp:24
Definition: EnumProcess.hpp:190
different physics engine has different winding order.
Definition: EventBinding.h:32
Definition: EnumProcess.hpp:142
Definition: EnumProcess.hpp:77
Definition: EnumProcess.hpp:100