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

📄 process.py

📁 wxPython的基本示例程序
💻 PY
📖 第 1 页 / 共 5 页
字号:
        try:            self._hProcess, self._hThread, self._processId, self._threadId\                = _SaferCreateProcess(                    None,           # app name                    cmd,            # command line                     None,           # process security attributes                     None,           # primary thread security attributes                     0,              # handles are inherited                     self._flags,    # creation flags                     self._env,      # environment                    self._cwd,      # current working directory                    si)             # STARTUPINFO pointer             win32api.CloseHandle(self._hThread)        except win32api.error, ex:            raise ProcessError(msg="Error creating process for '%s': %s"\                                   % (cmd, ex.args[2]),                               errno=ex.args[0])    def wait(self, timeout=None):         """Wait for the started process to complete.                "timeout" (on Windows) is a floating point number of seconds after            which to timeout.  Default is win32event.INFINITE.        "timeout" (on Unix) is akin to the os.waitpid() "options" argument            (os.WNOHANG may be used to return immediately if the process has            not exited). Default is 0, i.e. wait forever.        If the wait time's out it will raise a ProcessError. Otherwise it        will return the child's exit value (on Windows) or the child's exit        status excoded as per os.waitpid() (on Linux):            "a 16-bit number, whose low byte is the signal number that killed            the process, and whose high byte is the exit status (if the            signal number is zero); the high bit of the low byte is set if a            core file was produced."        In the latter case, use the os.W*() methods to interpret the return        value.        """        # XXX Or should returning the exit value be move out to another        #     function as on Win32 process control? If so, then should        #     perhaps not make WaitForSingleObject semantic transformation.        if sys.platform.startswith("win"):            if timeout is None:                timeout = win32event.INFINITE            else:                timeout = timeout * 1000.0 # Win32 API's timeout is in millisecs            rc = win32event.WaitForSingleObject(self._hProcess, timeout)            if rc == win32event.WAIT_FAILED:                raise ProcessError("'WAIT_FAILED' when waiting for process to "\                                   "terminate: %r" % self._cmd, rc)            elif rc == win32event.WAIT_TIMEOUT:                raise ProcessError("'WAIT_TIMEOUT' when waiting for process to "\                                   "terminate: %r" % self._cmd, rc)            retval = win32process.GetExitCodeProcess(self._hProcess)        else:            # os.waitpid() will raise:            #       OSError: [Errno 10] No child processes            # on subsequent .wait() calls. Change these semantics to have            # subsequent .wait() calls return the exit status and return            # immediately without raising an exception.            # (XXX It would require synchronization code to handle the case            # of multiple simultaneous .wait() requests, however we can punt            # on that because it is moot while Linux still has the problem            # for which _ThreadFixer() exists.)            if self.__retvalCache is not None:                retval = self.__retvalCache            else:                if timeout is None:                    timeout = 0                pid, sts = os.waitpid(self._pid, timeout)                if pid == self._pid:                    self.__retvalCache = retval = sts                else:                    raise ProcessError("Wait for process timed out.",                                       self.WAIT_TIMEOUT)        return retval    def kill(self, exitCode=0, gracePeriod=1.0, sig=None):        """Kill process.                "exitCode" [deprecated, not supported] (Windows only) is the            code the terminated process should exit with.        "gracePeriod" (Windows only) is a number of seconds the process is            allowed to shutdown with a WM_CLOSE signal before a hard            terminate is called.        "sig" (Unix only) is the signal to use to kill the process. Defaults            to signal.SIGKILL. See os.kill() for more information.        Windows:            Try for an orderly shutdown via WM_CLOSE.  If still running            after gracePeriod (1 sec. default), terminate.        """        if sys.platform.startswith("win"):            import win32gui            # Send WM_CLOSE to windows in this process group.            win32gui.EnumWindows(self._close_, 0)            # Send Ctrl-Break signal to all processes attached to this            # console. This is supposed to trigger shutdown handlers in            # each of the processes.            try:                win32api.GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,                                                  self._processId)            except AttributeError:                log.warn("The win32api module does not have "\                         "GenerateConsoleCtrlEvent(). This may mean that "\                         "parts of this process group have NOT been killed.")            except win32api.error, ex:                if ex.args[0] not in (6, 87):                    # Ignore the following:                    #   api_error: (87, 'GenerateConsoleCtrlEvent', 'The parameter is incorrect.')                    #   api_error: (6, 'GenerateConsoleCtrlEvent', 'The handle is invalid.')                    # Get error 6 if there is no console.                    raise                        # Last resort: call TerminateProcess if it has not yet.            retval = 0            try:                self.wait(gracePeriod)            except ProcessError, ex:                log.info("[%s] Process.kill: calling TerminateProcess", id(self))                win32process.TerminateProcess(self._hProcess, -1)                win32api.Sleep(100) # wait for resources to be released        else:            if sig is None:                sig = signal.SIGKILL            try:                os.kill(self._pid, sig)            except OSError, ex:                if ex.errno != 3:                    # Ignore:   OSError: [Errno 3] No such process                    raise    def _close_(self, hwnd, dummy):        """Callback used by .kill() on Windows.        EnumWindows callback - sends WM_CLOSE to any window owned by this        process.        """        threadId, processId = win32process.GetWindowThreadProcessId(hwnd)        if processId == self._processId:            import win32gui            win32gui.PostMessage(hwnd, WM_CLOSE, 0, 0)class ProcessOpen(Process):    """Create a process and setup pipes to it standard handles.    This is a super popen3.    """    # TODO:    #   - Share some implementation with Process and ProcessProxy.    #    def __init__(self, cmd, mode='t', cwd=None, env=None):        """Create a Process with proxy threads for each std handle.        "cmd" is the command string or argument vector to run.        "mode" (Windows only) specifies whether the pipes used to communicate            with the child are openned in text, 't', or binary, 'b', mode.            This is ignored on platforms other than Windows. Default is 't'.        "cwd" optionally specifies the directory in which the child process            should be started. Default is None, a.k.a. inherits the cwd from            the parent.        "env" is optionally a mapping specifying the environment in which to            start the child. Default is None, a.k.a. inherits the environment            of the parent.        """        # Keep a reference to ensure it is around for this object's destruction.        self.__log = log        log.info("ProcessOpen.__init__(cmd=%r, mode=%r, cwd=%r, env=%r)",                 cmd, mode, cwd, env)        self._cmd = cmd        if not self._cmd:            raise ProcessError("You must specify a command.")        self._cwd = cwd        self._env = env        self._mode = mode        if self._mode not in ('t', 'b'):            raise ProcessError("'mode' must be 't' or 'b'.")        self._closed = 0        if sys.platform.startswith("win"):            self._startOnWindows()        else:            self.__retvalCache = None            self._startOnUnix()        _registerProcess(self)    def __del__(self):        #XXX Should probably not rely upon this.        logres.info("[%s] ProcessOpen.__del__()", id(self))        self.close()        del self.__log # drop reference    def close(self):        if not self._closed:            self.__log.info("[%s] ProcessOpen.close()" % id(self))            # Ensure that all IOBuffer's are closed. If they are not, these            # can cause hangs.             try:                self.__log.info("[%s] ProcessOpen: closing stdin (%r)."\                                % (id(self), self.stdin))                self.stdin.close()            except AttributeError:                # May not have gotten far enough in the __init__ to set                # self.stdin, etc.                pass            try:                self.__log.info("[%s] ProcessOpen: closing stdout (%r)."\                                % (id(self), self.stdout))                self.stdout.close()            except AttributeError:                # May not have gotten far enough in the __init__ to set                # self.stdout, etc.                pass            try:                self.__log.info("[%s] ProcessOpen: closing stderr (%r)."\                                % (id(self), self.stderr))                self.stderr.close()            except AttributeError:                # May not have gotten far enough in the __init__ to set                # self.stderr, etc.                pass            self._closed = 1    def _forkAndExecChildOnUnix(self, fdChildStdinRd, fdChildStdoutWr,                                fdChildStderrWr):        """Fork and start the child process.        Sets self._pid as a side effect.        """        pid = os.fork()        if pid == 0: # child            os.dup2(fdChildStdinRd, 0)            os.dup2(fdChildStdoutWr, 1)            os.dup2(fdChildStderrWr, 2)            self._runChildOnUnix()        # parent        self._pid = pid    def _startOnUnix(self):        # Create pipes for std handles.        fdChildStdinRd, fdChildStdinWr = os.pipe()        fdChildStdoutRd, fdChildStdoutWr = os.pipe()        fdChildStderrRd, fdChildStderrWr = os.pipe()        if self._cwd:            oldDir = os.getcwd()            try:                os.chdir(self._cwd)            except OSError, ex:                raise ProcessError(msg=str(ex), errno=ex.errno)        self._forkAndExecChildOnUnix(fdChildStdinRd, fdChildStdoutWr,                                     fdChildStderrWr)        if self._cwd:            os.chdir(oldDir)        os.close(fdChildStdinRd)        os.close(fdChildStdoutWr)        os.close(fdChildStderrWr)        self.stdin = _FileWrapper(descriptor=fdChildStdinWr)        logres.info("[%s] ProcessOpen._start(): create child stdin: %r",                    id(self), self.stdin)        self.stdout = _FileWrapper(descriptor=fdChildStdoutRd)        logres.info("[%s] ProcessOpen._start(): create child stdout: %r",                    id(self), self.stdout)        self.stderr = _FileWrapper(descriptor=fdChildStderrRd)        logres.info("[%s] ProcessOpen._start(): create child stderr: %r",                    id(self), self.stderr)    def _startOnWindows(self):        if type(self._cmd) in (types.ListType, types.TupleType):            # An arg vector was passed in.            cmd = _joinArgv(self._cmd)        else:            cmd = self._cmd        # Create pipes for std handles.        # (Set the bInheritHandle flag so pipe handles are inherited.)        saAttr = pywintypes.SECURITY_ATTRIBUTES()        saAttr.bInheritHandle = 1        #XXX Should maybe try with os.pipe. Dunno what that does for        #    inheritability though.        hChildStdinRd, hChildStdinWr = win32pipe.CreatePipe(saAttr, 0)         hChildStdoutRd, hChildStdoutWr = win32pipe.CreatePipe(saAttr, 0)         hChildStderrRd, hChildStderrWr = win32pipe.CreatePipe(saAttr, 0)         try:            # Duplicate the parent ends of the pipes so they are not            # inherited.             hChildStdinWrDup = win32api.DuplicateHandle(                win32api.GetCurrentProcess(),                hChildStdinWr,                win32api.GetCurrentProcess(),                0,                0, # not inherited                DUPLICATE_SAME_ACCESS)            win32api.CloseHandle(hChildStdinWr)            self._hChildStdinWr = hChildStdinWrDup            hChildStdoutRdDup = win32api.DuplicateHandle(                win32api.GetCurrentProcess(),                hChildStdoutRd,                win32api.GetCurrentProcess(),                0,                0, # not inherited                DUPLICATE_SAME_ACCESS)            win32api.CloseHandle(hChildStdoutRd)            self._hChildStdoutRd = hChildStdoutRdDup            hChildStderrRdDup = win32api.DuplicateHandle(

⌨️ 快捷键说明

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