开发者

Python Unittest: Open and wait until the program is closed

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.

def test_HFG(self):
#....
print "please edit this file"
os.chdir(r'C:\test\a')
os.startfile("myfile.vdx")
# here I need a "s开发者_如何学Ctop until the program is closed"-function
#....

Does anyone have any idea how to realize(as simple as possible) my plan?


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])


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


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.


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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜