addon-sdk/source/python-lib/mozrunner/wpk.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/addon-sdk/source/python-lib/mozrunner/wpk.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,80 @@
     1.4 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.7 +
     1.8 +from ctypes import sizeof, windll, addressof, c_wchar, create_unicode_buffer
     1.9 +from ctypes.wintypes import DWORD, HANDLE
    1.10 +
    1.11 +PROCESS_TERMINATE = 0x0001
    1.12 +PROCESS_QUERY_INFORMATION = 0x0400
    1.13 +PROCESS_VM_READ = 0x0010
    1.14 +
    1.15 +def get_pids(process_name):
    1.16 +    BIG_ARRAY = DWORD * 4096
    1.17 +    processes = BIG_ARRAY()
    1.18 +    needed = DWORD()
    1.19 +
    1.20 +    pids = []
    1.21 +    result = windll.psapi.EnumProcesses(processes,
    1.22 +                                        sizeof(processes),
    1.23 +                                        addressof(needed))
    1.24 +    if not result:
    1.25 +        return pids
    1.26 +
    1.27 +    num_results = needed.value / sizeof(DWORD)
    1.28 +
    1.29 +    for i in range(num_results):
    1.30 +        pid = processes[i]
    1.31 +        process = windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION |
    1.32 +                                              PROCESS_VM_READ,
    1.33 +                                              0, pid)
    1.34 +        if process:
    1.35 +            module = HANDLE()
    1.36 +            result = windll.psapi.EnumProcessModules(process,
    1.37 +                                                     addressof(module),
    1.38 +                                                     sizeof(module),
    1.39 +                                                     addressof(needed))
    1.40 +            if result:
    1.41 +                name = create_unicode_buffer(1024)
    1.42 +                result = windll.psapi.GetModuleBaseNameW(process, module,
    1.43 +                                                         name, len(name))
    1.44 +                # TODO: This might not be the best way to
    1.45 +                # match a process name; maybe use a regexp instead.
    1.46 +                if name.value.startswith(process_name):
    1.47 +                    pids.append(pid)
    1.48 +                windll.kernel32.CloseHandle(module)
    1.49 +            windll.kernel32.CloseHandle(process)
    1.50 +
    1.51 +    return pids
    1.52 +
    1.53 +def kill_pid(pid):
    1.54 +    process = windll.kernel32.OpenProcess(PROCESS_TERMINATE, 0, pid)
    1.55 +    if process:
    1.56 +        windll.kernel32.TerminateProcess(process, 0)
    1.57 +        windll.kernel32.CloseHandle(process)
    1.58 +
    1.59 +if __name__ == '__main__':
    1.60 +    import subprocess
    1.61 +    import time
    1.62 +
    1.63 +    # This test just opens a new notepad instance and kills it.
    1.64 +
    1.65 +    name = 'notepad'
    1.66 +
    1.67 +    old_pids = set(get_pids(name))
    1.68 +    subprocess.Popen([name])
    1.69 +    time.sleep(0.25)
    1.70 +    new_pids = set(get_pids(name)).difference(old_pids)
    1.71 +
    1.72 +    if len(new_pids) != 1:
    1.73 +        raise Exception('%s was not opened or get_pids() is '
    1.74 +                        'malfunctioning' % name)
    1.75 +
    1.76 +    kill_pid(tuple(new_pids)[0])
    1.77 +
    1.78 +    newest_pids = set(get_pids(name)).difference(old_pids)
    1.79 +
    1.80 +    if len(newest_pids) != 0:
    1.81 +        raise Exception('kill_pid() is malfunctioning')
    1.82 +
    1.83 +    print "Test passed."

mercurial