Python Unittest: Open and wait until the program is closed

前端 未结 5 1434
醉酒成梦
醉酒成梦 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: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)
    

提交回复
热议问题