Python Unittest: Open and wait until the program is closed

前端 未结 5 1435
醉酒成梦
醉酒成梦 2021-01-16 05:55

Currently I try to create an unit test which opens a file (with the corresponding application) and then the test-run should wait until the program is closed.



        
相关标签:
5条回答
  • 2021-01-16 06:13

    From the docs:

    startfile() returns as soon as the associated application is launched. There is no option to wait for the application to close, and no way to retrieve the application’s exit status.

    If you know the path of the application to open the file with, you could use subprocess.Popen() which allows for you to wait.

    See: http://docs.python.org/library/os.html#os.startfile

    http://docs.python.org/library/subprocess.html#subprocess.Popen

    0 讨论(0)
  • 2021-01-16 06:21

    os.startfile is, of course, completely non-blocking with no options to wait.

    I'd recommend using the subprocess module, calling the Windows "start" command to open the file with the associated object, which does the same thing as os.startfile, but allows you to wait for the process to finish.

    e.g.:

    subprocess.call(["start", my_file])
    
    0 讨论(0)
  • 2021-01-16 06:32

    The documentation of os.startfile explicitly says:

    startfile() returns as soon as the associated application is launched. There is no option to wait for the application to close, and no way to retrieve the application’s exit status

    So, I recommend using an alternative method, such as launching it via subprocess.Popen, which does allow you to wait until the sub-process finishes.

    0 讨论(0)
  • 2021-01-16 06:32
    answer = raw_input("Please Edit this file (done): ")
    if answer == done:
        blablabla
    else:
        stop programm or whatever
    

    just let him tell you when he is done, simplest way i can imagine

    0 讨论(0)
  • 2021-01-16 06:35

    You can call the underlying windows APIs, as recommended in this C++ answer, either via pywin32:

    def start_file_wait(fname):
        import win32con
        import win32api
        import win32event
        from win32com.shell import shellcon
        from win32com.shell.shell import ShellExecuteEx
        rc = ShellExecuteEx(
            fMask=shellcon.SEE_MASK_NOCLOSEPROCESS,
            nShow=win32con.SW_SHOW,
            lpFile=fname)
        hproc = rc['hProcess']
        win32event.WaitForSingleObject(hproc, win32event.INFINITE)
        win32api.CloseHandle(hproc)
    

    or directly from ctypes:

    def startfile_wait(fname):
        import ctypes
        from ctypes.wintypes import ULONG, DWORD, HANDLE, HKEY, HINSTANCE, HWND, LPCWSTR
    
    
        class SHELLEXECUTEINFOW(ctypes.Structure):
            _fields_ = [
                ("cbSize", DWORD),
                ("fMask", ULONG),
                ("hwnd", HWND),
                ("lpVerb", LPCWSTR),
                ("lpFile", LPCWSTR),
                ("lpParameters", LPCWSTR),
                ("lpDirectory", LPCWSTR),
                ("nShow", ctypes.c_int),
                ("hInstApp", HINSTANCE),
                ("lpIDList", ctypes.c_void_p),
                ("lpClass", LPCWSTR),
                ("hkeyClass", HKEY),
                ("dwHotKey", DWORD),
                ("DUMMYUNIONNAME", ctypes.c_void_p),
                ("hProcess", HANDLE)
            ]
    
        shell_execute_ex = ctypes.windll.shell32.ShellExecuteExW
        shell_execute_ex.argtypes = [ctypes.POINTER(SHELLEXECUTEINFOW)]
        shell_execute_ex.res_type = ctypes.c_bool
    
        wait_for_single_object = ctypes.windll.kernel32.WaitForSingleObject
        wait_for_single_object.argtypes = [HANDLE, DWORD]
        wait_for_single_object.res_type = DWORD
    
        close_handle = ctypes.windll.kernel32.CloseHandle
        close_handle.argtypes = [HANDLE]
        close_handle.res_type = bool
    
        # https://stackoverflow.com/a/17638969/102441
        arg = SHELLEXECUTEINFOW()
        arg.cbSize = ctypes.sizeof(arg)
        arg.fMask = 0x00000040  # SEE_MASK_NOCLOSEPROCESS
        arg.hwnd = None
        arg.lpVerb = None
        arg.lpFile = fname
        arg.lpParameters = ""
        arg.lpDirectory = None
        arg.nShow = 10  # SW_SHOWDEFAULT
        arg.hInstApp = None
        ok = shell_execute_ex(arg)
        if not ok:
            raise ctypes.WinError()
        try:
            wait_for_single_object(arg.hProcess, -1)
        finally:
            close_handle(arg.hProcess)
    
    0 讨论(0)
提交回复
热议问题