WG: creating new process with pipes under win xp ->troubles

Michael Lieschnegg michael.lieschnegg at virtuellesfahrzeug.at
Tue Jul 19 08:22:30 CEST 2005


hello!

I wrote a python parent script which starts a separate script in a new
process (under Windows XP Pro SP2, Python 2.4.1).  Through anonymous
pipes I have a bidirectional communication to the child. Now I embedded
the parent script in a CPP program, but when I start the cpp dummy
application it seems as the application is producing copies of itself
(like a recursive function -> in the windows task manager the number of
the same process is increasing) and the child process is not working!
But when i start the parent script directly, it works well. Maybe you
can tell me the reason why it does not work in CPP.

Below you can find the the part of the code which is starting the client
process.

I hope you can help me. Thank you!

 

Michael Lieschnegg

 

I took following code from a closed forum to create the child process:

class Process:   

    def __init__(self, command, args, environment, path):

        # security attributes for pipes

        sAttrs = win32security.SECURITY_ATTRIBUTES()

        sAttrs.bInheritHandle = 1

 

        # create pipes

        hStdin_r,  self.hStdin_w  = win32pipe.CreatePipe(sAttrs, 0)

        self.hStdout_r, hStdout_w = win32pipe.CreatePipe(sAttrs, 0)

 

        # set the info structure for the new process.

        StartupInfo = win32process.STARTUPINFO()

        StartupInfo.hStdInput  = hStdin_r

        StartupInfo.hStdOutput = hStdout_w

        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

 

        

        # Create new output read handles and the input write handle. Set

        # the inheritance properties to FALSE. Otherwise, the child
inherits

        # the these handles; resulting in non-closeable handles to the
pipes

        # being created.

        pid = win32api.GetCurrentProcess()

 

        tmp = win32api.DuplicateHandle(

            pid,

            self.hStdin_w,

            pid,

            0,

            0,     # non-inheritable!!

            win32con.DUPLICATE_SAME_ACCESS)

        # Close the inhertible version of the handle

        win32file.CloseHandle(self.hStdin_w)

        self.hStdin_w = tmp

        

        tmp = win32api.DuplicateHandle(

            pid,

            self.hStdout_r,

            pid,

            0,

            0,     # non-inheritable!

            win32con.DUPLICATE_SAME_ACCESS)

        # Close the inhertible version of the handle

        win32file.CloseHandle(self.hStdout_r)

        self.hStdout_r = tmp

                

        # start the process.

        print "creating process"

        cmdline = "%s %s" % (command, string.join(args, ' '))

        hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(

                None,   # program

                cmdline,# command line

                None,   # process security attributes

                None,   # thread attributes

                1,      # inherit handles, or USESTDHANDLES won't work.

                        # creation flags. Don't access the console.

                0,      # Don't need anything here.

                        # If you're in a GUI app, you should use

                        # CREATE_NEW_CONSOLE here, or any subprocesses

                        # might fall victim to the problem described in:

                        # KB article: Q156755, cmd.exe requires

                        # an NT console in order to perform
redirection.. 

                environment,   # new environment

                path,          # new directory

                StartupInfo)

        # Child is launched. Close the parents copy of those pipe
handles

        # that only the child should have open.

        win32file.CloseHandle(hStdout_w)

        win32file.CloseHandle(hStdin_r)

 

        self.outQueue = Queue.Queue()

        self.closed = 0

        self.stdoutClosed = 0

     

        threading.Thread(target=self.doWrite).start()

 

    def write(self, data):

        self.outQueue.put(data)

    

    def closeStdin(self):

        self.outQueue.put(None)

    

    def connectionLost(self):

        if not self.closed:

            print "connection lost"

            self.closed = 1

            self.closeStdin()

            win32file.CloseHandle(self.hStdout_r)

    

    def doWrite(self):

        while 1:

            data = self.outQueue.get()

            if data == None:

                break

            try:

                win32file.WriteFile(self.hStdin_w, data, None)

            except win32api.error:

                print "error"

                break

        win32file.CloseHandle(self.hStdin_w)

    

    def doReadOut(self):

        try:

            hr, data = win32file.ReadFile(self.hStdout_r, 8192, None)

        except win32api.error:

            self.stdoutClosed = 1

            return

        self.handleData(data)

        return repr(data)

        

    def handleData(self, data):

        print "Got", repr(data)

        

if __name__ == '__main__':

    exe = win32api.GetModuleFileName(0)

    print exe

    p = Process(exe, ['-u', 'dispatcher.py', '8888'], None, None)

    print "ok, made process object"    

    while 1:

        p.write("hello, world! Who you are?\n")

        p.doReadOut()

 

When I run this script directly, the client process ("dispatcher.py")
will be started correctly. But when I create a instance of the class
Process in my cpp application, the client does not start and the cpp
application is producing and starting copies of  itself (it seems so).

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20050719/bbf898a6/attachment.html>


More information about the Python-list mailing list