subprocess.popen how wait complete open process

Eryk Sun eryksun at gmail.com
Mon Aug 22 09:47:06 EDT 2022


On 8/21/22, simone zambonardi <simone.zambonardi at gmail.com> wrote:
> Hi, I am running a program with the punishment subrocess.Popen(...) what I
> should do is to stop the script until the launched program is fully open.
> How can I do this? I used a time.sleep() function but I think there are
> other ways. Thanks

In Windows, WaitForInputIdle() waits until a thread in a process
creates one or more windows and its message loop goes idle. Usually
this is the main UI thread. Console processes are not supported.

For example:

import ctypes
import subprocess

user32 = ctypes.WinDLL('user32', use_last_error=True)

INFINITE = 0xFFFF_FFFF
WAIT_FAILED = 0xFFFF_FFFF
WAIT_TIMEOUT = 0x0000_0102

# Waiting on a console process fails with ERROR_NOT_GUI_PROCESS.
# This case be handled in other ways, depending on the need.
ERROR_NOT_GUI_PROCESS = 1471

user32.WaitForInputIdle.restype = ctypes.c_ulong
user32.WaitForInputIdle.argtypes = (ctypes.c_void_p, ctypes.c_ulong)

def wait_for_input_idle(proc, timeout=None):
    if isinstance(proc, subprocess.Popen):
        handle = int(proc._handle)
        args = p.args
    else:
        handle = int(proc)
        args = ''
    if timeout is None:
        timeout_ms = INFINITE
    elif timeout < 0:
        raise ValueError('timeout cannot be negative')
    else:
        timeout_ms = int(timeout * 1000)
        if timeout_ms >= INFINITE:
            raise OverflowError('timeout is too large')
    status = user32.WaitForInputIdle(handle, timeout_ms)
    if status == WAIT_FAILED:
        raise ctypes.WinError(ctypes.get_last_error())
    elif status == WAIT_TIMEOUT:
        raise subprocess.TimeoutExpired(args, timeout)
    assert status == 0
    return


if __name__ == '__main__':
    import time
    t0 = time.time()
    p = subprocess.Popen(['pythonw.exe', '-m', 'idlelib'])

    try:
        wait_for_input_idle(p, 5)
    except:
        p.terminate()
        raise

    wait_time = time.time() - t0
    print(f'wait time: {wait_time:.3f} seconds')
    try:
        p.wait(5)
    except subprocess.TimeoutExpired:
        p.terminate()


More information about the Python-list mailing list