What's wrong on using Popen's communicate method?
Terry Reedy? 2019?7?5???? UTC+8??12?13?25????
> On 7/3/2019 7:57 PM, jfong at ms4.hinet.net wrote:
> > I have the test0.py below. I expect to see 'abcd' showing in the notepad window:
> > ---------
> > import subprocess as sp
> > p0 = sp.Popen('notepad.exe', stdin=sp.PIPE)
> > p0.communicate(input=b'abcd')
> > ---------
> > But nothing happens. The notepad is completely empty. What have I missed?
> > --Jach
> > PS. I am using python 3.4 on Windows Vista
> Upgrade to 3.7 or 3.8 to get hundreds of bug fixes, let alone new
> features. Both subprocess and multiprocessing have gotten fixes.
I can't because my OS is Vista and v3.4 is the last it can run:-( Also the pywin32 can't be installed for it requires v3.5 and up.
> subprocess is meant for running an external program in batch mode. It
> receives the one input byte string, sends output, and closes. For
> interaction, try multiprocessing.
> Or do what IDLE does, which is to open a two-way socket to the parent
> program. (Managing this is not fun.) IDLE was initially written before
> multiprocessing. It has been suggested to me that it should switch to
> multiprocessing. (But last I read, multiprocessing and tkinter (tcl/tk)
> do not play well together on macOS.)
Can multiprocessing make debugging of eventloop app easier?
> If the subprocess runs a gui, the user should be able to switch focus by
> clicking on a subprocess window.
I finally get a solution to switch between two notepads in Python. Here is the codes for someone he may be interested.
import subprocess, time, ctypes
user32 = ctypes.windll.user32
p0 = subprocess.Popen('notepad.exe')
handle0 = user32.GetForegroundWindow() # the handler of foreground window
thread0 = user32.GetWindowThreadProcessId(handle0, 0) # get its thread id
p1 = subprocess.Popen('notepad.exe')
handle1 = user32.GetForegroundWindow()
thread1 = user32.GetWindowThreadProcessId(handle1, 0)
for i in range(3): # suppose the notepad1 is the foreground window
time.sleep(5) # delay enough time for typing test
user32.AttachThreadInput(thread1, thread0, True)
user32.AttachThreadInput(thread0, thread1, True)