⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.py

📁 wxPython的基本示例程序
💻 PY
📖 第 1 页 / 共 5 页
字号:
        if ' ' in cmd:            first, rest = cmd.split(' ', 1)        else:            first, rest = cmd, ""    # Ensure the first arg is a valid path to the appropriate file.    import which    if os.sep in first:        altpath = [os.path.dirname(first)]        firstbase = os.path.basename(first)        candidates = list(which.which(firstbase, path=altpath))    elif env:        altpath = _getPathFromEnv(env)        if altpath:            candidates = list(which.which(first, altpath.split(os.pathsep)))        else:            candidates = list(which.which(first))    else:        candidates = list(which.which(first))    if candidates:        return _joinArgv( [candidates[0]] ) + ' ' + rest    else:        raise ProcessError("Could not find an appropriate leading command "\                           "for: %r" % cmd)if sys.platform.startswith("win"):    def _SaferCreateProcess(appName,        # app name                            cmd,            # command line                             processSA,      # process security attributes                             threadSA,       # thread security attributes                             inheritHandles, # are handles are inherited                            creationFlags,  # creation flags                             env,            # environment                            cwd,            # current working directory                            si):            # STARTUPINFO pointer        """If CreateProcess fails from environment type inconsistency then        fix that and try again.                win32process.CreateProcess requires that all environment keys and        values either be all ASCII or all unicode. Try to remove this burden        from the user of process.py.        """        isWin9x = win32api.GetVersionEx()[3] == VER_PLATFORM_WIN32_WINDOWS        # On Win9x all keys and values of 'env' must be ASCII (XXX        # Actually this is probably only true if the Unicode support        # libraries, which are not installed by default, are not        # installed). On other Windows flavours all keys and values of        # 'env' must all be ASCII *or* all Unicode. We will try to        # automatically convert to the appropriate type, issuing a        # warning if such an automatic conversion is necessary.        #XXX Komodo 2.0 Beta 1 hack. This requirement should be        #    pushed out to Komodo code using process.py. Or should it?        if isWin9x and env:            aenv = {}            for key, value in env.items():                aenv[str(key)] = str(value)            env = aenv                log.debug("""\_SaferCreateProcess(appName=%r,                    cmd=%r,                    env=%r,                    cwd=%r)    os.getcwd(): %r""", appName, cmd, env, cwd, os.getcwd())        try:            hProcess, hThread, processId, threadId\                = win32process.CreateProcess(appName, cmd, processSA,                                             threadSA, inheritHandles,                                             creationFlags, env, cwd, si)        except TypeError, ex:            if ex.args == ('All dictionary items must be strings, or all must be unicode',):                # Try again with an all unicode environment.                #XXX Would be nice if didn't have to depend on the error                #    string to catch this.                #XXX Removing this warning for 2.3 release. See bug                #    23215. The right fix is to correct the PHPAppInfo                #    stuff to heed the warning.                #import warnings                #warnings.warn('env: ' + str(ex), stacklevel=4)                if isWin9x and env:                    aenv = {}                    try:                        for key, value in env.items():                            aenv[str(key)] = str(value)                    except UnicodeError, ex:                        raise ProcessError(str(ex))                    env = aenv                elif env:                    uenv = {}                    for key, val in env.items():                        try:                            uenv[unicode(key)] = unicode(val)   # default encoding                        except UnicodeError:                            try:                                uenv[unicode(key, 'iso-8859-1')] = unicode(val, 'iso-8859-1')   # backup encoding                            except UnicodeError:                                log.warn('Skipping environment variable "%s" in execution process: unable to convert to unicode using either the default encoding or ISO-8859-1' % (key))                    env = uenv                hProcess, hThread, processId, threadId\                    = win32process.CreateProcess(appName, cmd, processSA,                                                 threadSA, inheritHandles,                                                 creationFlags, env, cwd,                                                 si)            else:                raise        return hProcess, hThread, processId, threadId# Maintain references to all spawned ProcessProxy objects to avoid hangs.#   Otherwise, if the user lets the a ProcessProxy object go out of#   scope before the process has terminated, it is possible to get a#   hang (at least it *used* to be so when we had the#   win32api.CloseHandle(<stdin handle>) call in the __del__() method).#   XXX Is this hang possible on Linux as well?# A reference is removed from this list when the process's .wait or# .kill method is called.# XXX Should an atexit() handler be registered to kill all curently#     running processes? Else *could* get hangs, n'est ce pas?def _registerProcess(process):    global _processes    log.info("_registerprocess(process=%r)", process)    # Clean up zombie processes.    #   If the user does not call .wait() or .kill() on processes then    #   the ProcessProxy object will not get cleaned up until Python    #   exits and _processes goes out of scope. Under heavy usage that    #   is a big memory waste. Cleaning up here alleviates that.    for p in _processes[:]: # use copy of _process, because we may modifiy it        try:            # poll to see if is process still running            if sys.platform.startswith("win"):                timeout = 0            else:                timeout = os.WNOHANG            p.wait(timeout)            _unregisterProcess(p)        except ProcessError, ex:            if ex.errno == ProcessProxy.WAIT_TIMEOUT:                pass            else:                raise            _processes.append(process)def _unregisterProcess(process):    global _processes    log.info("_unregisterProcess(process=%r)", process)    try:        _processes.remove(process)        del process    except ValueError:        passdef _fixupCommand(cmd, env=None):    """Fixup the command string so it is launchable via CreateProcess.    One cannot just launch, say "python", via CreateProcess. A full path    to an executable is required. In general there are two choices:        1. Launch the command string via the shell. The shell will find           the fullpath to the appropriate executable. This shell will           also be able to execute special shell commands, like "dir",           which don't map to an actual executable.        2. Find the fullpath to the appropriate executable manually and           launch that exe.    Option (1) is preferred because you don't have to worry about not    exactly duplicating shell behaviour and you get the added bonus of    being able to launch "dir" and friends.    However, (1) is not always an option. Doing so when the shell is    command.com (as on all Win9x boxes) or when using WinNT's cmd.exe,    problems are created with .kill() because these shells seem to eat    up Ctrl-C's and Ctrl-Break's sent via    win32api.GenerateConsoleCtrlEvent().  Strangely this only happens    when spawn via this Python interface. For example, Ctrl-C get    through to hang.exe here:      C:\> ...\w9xpopen.exe "C:\WINDOWS\COMMAND.COM /c hang.exe"      ^C    but not here:      >>> p = ProcessOpen('hang.exe')      # This results in the same command to CreateProcess as      # above.      >>> p.kill()    Hence, for these platforms we fallback to option (2).  Cons:      - cannot spawn shell commands like 'dir' directly      - cannot spawn batch files    """    if sys.platform.startswith("win"):        # Fixup the command string to spawn.  (Lifted from        # posixmodule.c::_PyPopenCreateProcess() with some modifications)        comspec = os.environ.get("COMSPEC", None)        win32Version = win32api.GetVersion()        if comspec is None:            raise ProcessError("Cannot locate a COMSPEC environment "\                               "variable to use as the shell")        # Explicitly check if we are using COMMAND.COM.  If we        # are then use the w9xpopen hack.        elif (win32Version & 0x80000000L == 0) and\             (win32Version &        0x5L >= 5) and\             os.path.basename(comspec).lower() != "command.com":            # 2000/XP and not using command.com.            if '"' in cmd or "'" in cmd:                cmd = comspec + ' /c "%s"' % cmd            else:                cmd = comspec + ' /c ' + cmd        elif (win32Version & 0x80000000L == 0) and\             (win32Version &        0x5L  < 5) and\             os.path.basename(comspec).lower() != "command.com":            # NT and not using command.com.            try:                cmd = _whichFirstArg(cmd, env)            except ProcessError:                raise ProcessError("Could not find a suitable executable "\                    "to launch for '%s'. On WinNT you must manually prefix "\                    "shell commands and batch files with 'cmd.exe /c' to "\                    "have the shell run them." % cmd)        else:            # Oh gag, we're on Win9x and/or using COMMAND.COM. Use the            # workaround listed in KB: Q150956            w9xpopen = os.path.join(                os.path.dirname(win32api.GetModuleFileName(0)),                'w9xpopen.exe')            if not os.path.exists(w9xpopen):                # Eeek - file-not-found - possibly an embedding                # situation - see if we can locate it in sys.exec_prefix                w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix),                                        'w9xpopen.exe')                if not os.path.exists(w9xpopen):                    raise ProcessError(\                        "Can not locate 'w9xpopen.exe' which is needed "\                        "for ProcessOpen to work with your shell or "\                        "platform.")            ## This would be option (1):            #cmd = '%s "%s /c %s"'\            #      % (w9xpopen, comspec, cmd.replace('"', '\\"'))            try:                cmd = _whichFirstArg(cmd, env)            except ProcessError:                raise ProcessError("Could not find a suitable executable "\                    "to launch for '%s'. On Win9x you must manually prefix "\                    "shell commands and batch files with 'command.com /c' "\                    "to have the shell run them." % cmd)            cmd = '%s "%s"' % (w9xpopen, cmd.replace('"', '\\"'))    return cmdclass _FileWrapper:    """Wrap a system file object, hiding some nitpicky details.        This class provides a Python file-like interface to either a Python    file object (pretty easy job), a file descriptor, or an OS-specific    file handle (e.g.  Win32 handles to file objects on Windows). Any or    all of these object types may be passed to this wrapper. If more    than one is specified this wrapper prefers to work with certain one    in this order:        - file descriptor (because usually this allows for          return-immediately-on-read-if-anything-available semantics and          also provides text mode translation on Windows)        - OS-specific handle (allows for the above read semantics)        - file object (buffering can cause difficulty for interacting          with spawned programs)    It also provides a place where related such objects can be kept    alive together to prevent premature ref-counted collection. (E.g. on    Windows a Python file object may be associated with a Win32 file    handle. If the file handle is not kept alive the Python file object    will cease to function.)    """    def __init__(self, file=None, descriptor=None, handle=None):        self._file = file        self._descriptor = descriptor        self._handle = handle        self._closed = 0        if self._descriptor is not None or self._handle is not None:            self._lineBuf = "" # to support .readline()    def __del__(self):        self.close()    def __getattr__(self, name):        """Forward to the underlying file object."""        if self._file is not None:            return getattr(self._file, name)        else:            raise ProcessError("no file object to pass '%s' attribute to"                               % name)    def _win32Read(self, nBytes):        try:            log.info("[%s] _FileWrapper.read: waiting for read on pipe",                     id(self))            errCode, text = win32file.ReadFile(self._handle, nBytes)        except pywintypes.error, ex:            # Ignore errors for now, like "The pipe is being closed.",            # etc. XXX There *may* be errors we don't want to avoid.            log.info("[%s] _FileWrapper.read: error reading from pipe: %s",                     id(self), ex)            return ""        assert errCode == 0,\               "Why is 'errCode' from ReadFile non-zero? %r" % errCode        if not text:            # Empty text signifies that the pipe has been closed on            # the parent's end.            log.info("[%s] _FileWrapper.read: observed close of parent",                     id(self))            # Signal the child so it knows to stop listening.            self.close()            return ""        else:            log.info("[%s] _FileWrapper.read: read %d bytes from pipe: %r",                     id(self), len(text), text)        return text

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -