Example #1
0
        def detach(cls):
            script = sys.argv[0]
            sys.argv.append('--detached')
            if special in sys.argv:
                sys.argv.remove(special)
                return 0  #we're in the child just return

            #we're in the parent do stuff
            try:
                from subprocess import CreateProcess

                class STARTUPINFO:
                    dwFlags = 0
                    hStdInput = None
                    hStdOutput = None
                    hStdError = None

                class pywintypes:
                    error = IOError
            except ImportError:
                try:
                    from win32process import CreateProcess, STARTUPINFO
                except ImportError:
                    return 1, "Can't import CreateProcess from subprocess or win32process"
            exe = sys.executable.replace('n.exe', 'nw.exe')
            startupinfo = STARTUPINFO()
            args = ''.join([' "%s"' % a for a in sys.argv[1:]])
            cmd = '"%s" "%s"%s %s' % (exe, script, args, special)
            try:
                hp, ht, pid, tid = CreateProcess(
                    None,
                    cmd,
                    # no special security
                    None,
                    None,
                    0,  #don't inherit standard handles
                    0x208,
                    None,
                    None,
                    startupinfo)
            except pywintypes.error, e:
                return 2, str(e)
Example #2
0
        def _execute_child(self, args, executable, preexec_fn, close_fds, cwd,
                           env, universal_newlines, startupinfo, creationflags,
                           shell, p2cread, p2cwrite, c2pread, c2pwrite,
                           errread, errwrite):
            """Execute program (MS Windows version)"""

            if not isinstance(args, str):
                args = list2cmdline(args)

            # Process startup details
            if startupinfo is None:
                startupinfo = STARTUPINFO()
            if None not in (p2cread, c2pwrite, errwrite):
                startupinfo.dwFlags |= STARTF_USESTDHANDLES
                startupinfo.hStdInput = p2cread
                startupinfo.hStdOutput = c2pwrite
                startupinfo.hStdError = errwrite

            if shell:
                startupinfo.dwFlags |= STARTF_USESHOWWINDOW
                startupinfo.wShowWindow = SW_HIDE
                comspec = os.environ.get("COMSPEC", "cmd.exe")
                args = comspec + " /c " + args
                if (GetVersion() >= 0x80000000
                        or os.path.basename(comspec).lower() == "command.com"):
                    # Win9x, or using command.com on NT. We need to
                    # use the w9xpopen intermediate program. For more
                    # information, see KB Q150956
                    # (http://web.archive.org/web/20011105084002/http://support.microsoft.com/support/kb/articles/Q150/9/56.asp)
                    w9xpopen = self._find_w9xpopen()
                    args = '"%s" %s' % (w9xpopen, args)
                    # Not passing CREATE_NEW_CONSOLE has been known to
                    # cause random failures on win9x.  Specifically a
                    # dialog: "Your program accessed mem currently in
                    # use at xxx" and a hopeful warning about the
                    # stability of your system.  Cost is Ctrl+C wont
                    # kill children.
                    creationflags |= CREATE_NEW_CONSOLE

                # We create a new job for this process, so that we can kill
                # the process and any sub-processes
                self._job = winprocess.CreateJobObject()
                creationflags |= winprocess.CREATE_SUSPENDED
                # Vista will launch Komodo in a job object itself, so we need
                # to specify that the created process is not part of the Komodo
                # job object, but instead specify that it will be using a
                # separate breakaway job object, bug 83001.
                creationflags |= winprocess.CREATE_BREAKAWAY_FROM_JOB

            # Start the process
            try:
                hp, ht, pid, tid = CreateProcess(
                    executable,
                    args,
                    # no special security
                    None,
                    None,
                    int(not close_fds),
                    creationflags,
                    env,
                    cwd,
                    startupinfo)
            except pywintypes.error as e:
                # Translate pywintypes.error to WindowsError, which is
                # a subclass of OSError.  FIXME: We should really
                # translate errno using _sys_errlist (or simliar), but
                # how can this be done from Python?
                raise WindowsError(*e.args)
            except WindowsError:
                log.error("process.py: can't execute %r (%s)", executable,
                          args)
                raise

            # Retain the process handle, but close the thread handle
            self._child_created = True
            self._handle = hp
            self.pid = pid
            if self._job:
                # Resume the thread.
                winprocess.AssignProcessToJobObject(self._job, int(hp))
                winprocess.ResumeThread(int(ht))
            ht.Close()

            # Child is launched. Close the parent's copy of those pipe
            # handles that only the child should have open.  You need
            # to make sure that no handles to the write end of the
            # output pipe are maintained in this process or else the
            # pipe will not close when the child process exits and the
            # ReadFile will hang.
            if p2cread is not None:
                p2cread.Close()
            if c2pwrite is not None:
                c2pwrite.Close()
            if errwrite is not None:
                errwrite.Close()