wpk.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. # This Source Code Form is subject to the terms of the Mozilla Public
  2. # License, v. 2.0. If a copy of the MPL was not distributed with this
  3. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. from ctypes import sizeof, windll, addressof, c_wchar, create_unicode_buffer
  5. from ctypes.wintypes import DWORD, HANDLE
  6. PROCESS_TERMINATE = 0x0001
  7. PROCESS_QUERY_INFORMATION = 0x0400
  8. PROCESS_VM_READ = 0x0010
  9. def get_pids(process_name):
  10. BIG_ARRAY = DWORD * 4096
  11. processes = BIG_ARRAY()
  12. needed = DWORD()
  13. pids = []
  14. result = windll.psapi.EnumProcesses(processes,
  15. sizeof(processes),
  16. addressof(needed))
  17. if not result:
  18. return pids
  19. num_results = needed.value / sizeof(DWORD)
  20. for i in range(num_results):
  21. pid = processes[i]
  22. process = windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION |
  23. PROCESS_VM_READ,
  24. 0, pid)
  25. if process:
  26. module = HANDLE()
  27. result = windll.psapi.EnumProcessModules(process,
  28. addressof(module),
  29. sizeof(module),
  30. addressof(needed))
  31. if result:
  32. name = create_unicode_buffer(1024)
  33. result = windll.psapi.GetModuleBaseNameW(process, module,
  34. name, len(name))
  35. # TODO: This might not be the best way to
  36. # match a process name; maybe use a regexp instead.
  37. if name.value.startswith(process_name):
  38. pids.append(pid)
  39. windll.kernel32.CloseHandle(module)
  40. windll.kernel32.CloseHandle(process)
  41. return pids
  42. def kill_pid(pid):
  43. process = windll.kernel32.OpenProcess(PROCESS_TERMINATE, 0, pid)
  44. if process:
  45. windll.kernel32.TerminateProcess(process, 0)
  46. windll.kernel32.CloseHandle(process)
  47. if __name__ == '__main__':
  48. import subprocess
  49. import time
  50. # This test just opens a new notepad instance and kills it.
  51. name = 'notepad'
  52. old_pids = set(get_pids(name))
  53. subprocess.Popen([name])
  54. time.sleep(0.25)
  55. new_pids = set(get_pids(name)).difference(old_pids)
  56. if len(new_pids) != 1:
  57. raise Exception('%s was not opened or get_pids() is '
  58. 'malfunctioning' % name)
  59. kill_pid(tuple(new_pids)[0])
  60. newest_pids = set(get_pids(name)).difference(old_pids)
  61. if len(newest_pids) != 0:
  62. raise Exception('kill_pid() is malfunctioning')
  63. print "Test passed."