Python: Redirect output to several consoles? - python

I have a main program, in which a user can call a sub-process (to download files) several times. Each time, I call aria2c using subprocess, and it will print the progress to stdin. Of course, it is desirable that the user can see the progress of each download seperately.
So the question is how can I redirect the output of each process to a seperate console window?

I'm a bit confused. Using subprocess.Popen(...) should spawn a new command prompt automatically for each call. What is aria2c? Is it a program you had written in python as well? Is it a 3rd party exe that writes to the command prompt window?
I can help you to redirect all the sub-processes output to the main command prompt, so it can be displayed inline.
Also, maybe you can give a little more detail on what is going on first, so I can understand your trouble a bit better.

Related

How to show program on the screen if it was opened?

I have a problem with how to show a program window if it was opened
how I open it is using
import os
os.startfile('path/to/progarm.exe')
But if progarm.exe is opened and I forgot to close
when I run that script again, A program.exe doesn't show on the
screen when I was on another window.
So which script can show up the opened program?
The main reason is that your script lost the focus the opened programs windows.
You can control windows with parameters.
os.startfile(path[, operation][, arguments][, cwd][, show_cmd])
also, you can check detail information here.
https://docs.python.org/3/library/os.html#os.startfile
To do what you want, you need to provide the path to the program in your machine.
import os
ms_word = r"C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE"
os.startfile(ms_word)
I would not recommend doing what you are doing the way you are doing it.
Python has a subprocess module to do things like these, with functions specifically designed to do what you are doing. The easiest way to do what you are trying to do is to use the subprocess.runfunction.
import subprocess
subprocess.run(['path/to/app.exe', 'param1', 'param2'..], shell=True, check=True)
# params are optional.
However, subprocess.run is blocking, i.e., the script will not exit unless you close your launched application.
You can in that case use the subprocess.Popen class. This invokes the process and allows you to communicate with it asynchronously. However, if your objective is only to launch an app and shut down your script, then just call it as you made a call to run. The links I have provided has some examples. there are platform level considerations to make in the case of the parent-child process relationships, e.g. keep child running if the parent dies, kill the child with the parent, keep both of them running independently and allow them to die separately. probably this answer and this answer would provide you with some hints.
However, if you just want to launch an application and nothing else, just use the system shell, no?

Python3 - Issues with "subprocess.call()" function

my software uses the subprocess.call([sys.executable, SCRIPT_NAME] instruction in order to open others kind of scripts specified by the user using a GUI (Tkinter). I have two issue with this instruction:
the "command line" scripts start and close themeselves quicly and it means that the user can't interact with them. it's a weird behaviour because in all of them there is an input instruction, so they should wait an input by the user before to close themeselves. how can I solve this issue?
the "GUI" scripts instead, start without any kind of issue, but their "life", let me say, put in stuck the main script (it uses Tkinter). in this case I can interact with the second script but not with the main one. how can I call my other scripts with the subprocess.call() function whithout put in stuck the main one? from my point of view this issue happens because the second script is a part of the same process of the main one and in this case Tkinter has to wait. if we open the others scripts using different processes for all of them the main script would be free to live its life independently of the others. but how can I do it?

Running an interactive Python script from a Batch File

I am wanting to run an interactive Python Program from a Batch File. I found the answer to the question "pythonw.exe or python.exe?" helpful, but not all the issues I had in mind were resolved. I decided to experiment using con:.
The following demonstrates the kind of interaction I have achieved:
Microsoft Windows [Version 10.0.18362.476]
(c) 2019 Microsoft Corporation. All rights reserved.
c:\sjt\PY\NEWER>type call_py.bat
#echo off
call python c:\sjt\py\newer\testout.py 1>con: 2>con:
c:\sjt\PY\NEWER>type testout.py
print ("Print works if you can see this.")
strwaiter = raw_input ("raw_input prompt: ")
print ("This string was received by strwaiter in response to the prompt: " + strwaiter)
c:\sjt\PY\NEWER>call_py
Print works if you can see this.
raw_input prompt: Here is my response.
This string was received by strwaiter in response to the prompt: Here is my response.
c:\sjt\PY\NEWER>
I tried running call_py.bat again but with it calling pythonw instead of python, this attempt did not produce the desired result.
Also, during my experimenting, I tried calling python without the redirection of 1 and 2. This, likewise, was unsuccessful.
I attempted to add a comment to the relevant answer to that question, but failed because I do not have the required reputation. I am posting this question instead.
Does my experiment add anything to the answers to that question?
Given that I know nothing about the technical details given in that post, why is it that calling python in my batch file works (with these redirections) but calling pythonw doesn't?
PS See start /? about differences in starting types of exe files.
There are two types of programs in Windows. Graphical and console, or another way of saying it is console and non-console. The difference is that console programs automatically get or inherit (if there is an existing one) a console window. And thus get access to StdIn etc (which don't exist in the non console world).
If a program gets a console or not is controlled by a flag in the program file's header.
Typically console programs act as console programs, but they don't have too. They can have windows if they want.
Typically GUI programs don't do console stuff, but if they want they can attach to their parent's console and act as a console programs.
Programs without any UI are GUI programs. GUI program just means no console. If a program wants windows it has to create them.
To give you an idea. If you were to take Notepads's source code and compile it as a console program (by changing an option in the compiler). When you start it a console window will open (or it will inherit the current one) and the normal Notepad window will open. As Notepad doesn't have any code to interact with a console the console will just sit there.
One use for writing graphical programs and compiling them as console is that you use the console window for debugging information. Also if the program crashes error information is written to the console (rather than some deeply buried Problem Report that takes 50 clicks to get to).
The other thing to note is that Windows fully communicates to programs via a window. Console programs have to have threads to process messages and receive very limited messages mainly about the console closing or the user closed your program.
Windows messages are many. Even programs without a user interface will typically create a hidden window to receive messages (like shutdown, sleep, wallpaper changed, USB drive arrived, close program, etc).
On my computer with 4 apps visible I have a total of 410 windows.
https://winsourcecode.blogspot.com/2019/05/winlistexe-list-open-windows-and-their.html
This is Microsoft's Documentation of processes.
https://learn.microsoft.com/en-us/windows/console/about-character-mode-applications
https://learn.microsoft.com/en-us/windows/win32/procthread/processes-and-threads

is it possible to launch a window that does not stop the mainloop in python

OS = windows 7
I have a python program (works) that is listening to activity on the usb bus. I want to perform a lot of tests that require a particular user input at a particular time. I would like to pop up a window that says, "press button xxx". The key point is that the mainloop needs to continue running because it's looking for events. I don't care about the window or if it remains or not and I don't need to capture any information from the window. I just want a message to the user to press the correct button at the correct time. Any type of signaling would work; it doesn't have to be a gui window. It doesn't have to look pretty. Appreciate any suggestions or links to something like this. thx
It sounds like the operation of the Python script you're running does not depend upon the user input you request. To run another process without interrupting the Python script execution you can use:
import subprocess
subprocess.Popen([exe,arg1,arg2,arg3])
where
exe = executable/script to run from your OS command line
arg1= first argument to pass to exe
arg2= second argument to pass to exe
etc... (as many arguments as your OS supports in a list)
This separate exe process could request input from the user.

How to make a python script launched from subprocess.Popen stay open if an error occurs and closes when it returns normally?

Currently, I'm running this on Windows:
args = ['start', windowname, 'python', '-i', myscript]
subprocess.Popen(args, shell=True)
As you can see, I launch a subprocess running myscript in python's interactive mode. In my case, this means that once the script exits, regardless if it errors out or successfully completes, the window/shell stays open. However, I'd like it so that when myscript errors out, the window will stay open, and when myscript runs successfully, the window will close.
The reason I'm doing this is because I want to see the errors and the output leading up to the errors -- I'd prefer to not use some form of logging because it's easier for me to visually see the windows and outputs.
I don't think I can check the returncode because the process I'm interacting with is start/cmd, rather than python. Please correct me if I'm wrong!
Thanks!
I think the easiest way would be to wrap the whole thing in a small batch script that checks for python's return code (presumably set by you by calling sys.exit() with an appropriate return code).
This stackoverflow question covers how to get the return code (apparently it's in %errorlevel%), and you can keep the cmd window open by executing pause in a batch script.

Categories

Resources