Running an interactive Python script from a Batch File - python

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

Related

Send keystrokes to non-active GUI application without occupying the keyboard

As the title explain, i'm trying to use the terminal to send commands as keystrokes to a GUI application that's minimized.
There is a lot of similar questions here on Stack with some great answers, but i'm having, mainly, three problems with the solutions i saw: Most of the solutions need the automated application to be the active one. Or, i can't normally use my keyboard while the script/process is running. Or worse, the solution works only on Windows OS.
I need what this person asked 2 months ago: Send keystrokes to a specific window (in background), but do something else in the meantime
But i want it on Linux.
I'm using Kubuntu 18.10, if that helps.
xdotool was close, but i couldn't quite get it to send the commands to a specific window or PID. It also uses "my keyboard", so i can't, for example, write an essay/code/browse online while xdotool is running. Pexpect also have this last problem.
AutoHotKey looks like it would work, but it's only for Windows and i'm trying to not use Wine. Same with pywin32.
keyboard (https://github.com/boppreh/keyboard) seems nice, but it can't send a command to a specific application. Same with PyAutoGUI.
I selected the Python tag because most of the solutions i saw use Python, but i'm open to any language.
Use a nested X server to input keystrokes without changing focus or keyboard grab.
Proof of concept:
Xephyr -resizeable :13
export DISPLAY=:13
xterm
xdotool type rhabarber
The Xephyr nested X server is started and will listen on local X socket 13 (whereas :0 typically identifies the currently running X server, but when multiple sessions are ran concurrently, it could be higher).
Then we set DISPLAY environment variable to :13, so any X application we start will connect to Xephyr; xterm is our target application here. Using xdotool or any other tool we can send keystrokes.
As the target X server is identified through $DISPLAY, applications can be started or input events triggered from elsewhere as well. If needed, you might also run a lightweight window manager within Xephyr, e.g. to 'maximize' the application so that it fills the whole Xephyr window.

Can I keep the terminal as the active window, even if it's in the background? - Python 3.3

G'day,
I've just posted this question here. Following on from that, is there a means to lock keyboard user input to the terminal, when it's running behind another window? My system requires a user to scan their barcode (barcode scanner acts as a keyboard. ie. outputs a string of letters and presses enter) inside the terminal. However, the system also requires that a log CSV file be displayed on the attached monitor. As such, with the terminal in the background, the cursor automatically reverts to the log CSV file when opened, which disables the users' barcode scan from being entered into the terminal.
I'm still relatively new to Python, and haven't completely figured out the functionality of this system. I will eventually set it up such that when the system boots, the log file will automatically open on top, with the terminal (and cursor input) running in the background.
Again, I don't have any code to demonstrate my attempts, but I have done extensive research. The only thing I've found that may offer this functionality is xdotool. I could automatically rearrange the windows such that the terminal was always at the back, and somehow automatically allocate the terminal as the 'active' window?
Any help here would be great!
Thanks!

Python shell issue when using Data Nitro

I am using DataNitro to write Python Script in Excel. Its very useful indeed. However, when I open the Idle editor in excel, the accompanying Python Shell is not interactive, in that it does not return print statements, show errors, nothing. It just restarts every time I run the programme. This makes it incredibly hard to debug as I can't use print statements to trace the errors.
Does anyone know if this is a bug with DataNitro, or is it supposed to be that way, or whats going on? are there any solutions?
Thanks so much
Our IDLE editor is just an editor - it doesn't work as a shell.
The best way to debug programs is to raise an exception. This will freeze the shell that opens when a script is run, and you'll be able to inspect the variables and see any print statements that were generated during execution.
For example, if you run:
print Cell("A1").value
x = Cell("B1").value
raise
You'll see the value of A1 printed to the shell, and you can enter "x" at the prompt to see the value of B1.
You can also import a script you're working on into the regular Python shell (the one that opens when you press "shell"). This will execute the code in that script.
We'll be adding a guide to debugging code to the site soon, as well as some features that make it easier.
Source: I'm one of the founders of DataNitro.
Not as knowledgeable as Ben, but have been using DataNitro quite a bit and here are some tips:
The shell automatically closes once the script has run. If you want to inspect some prints or even interact with the shell I normally place following at end of my script.
raw_input("Press Enter to Exit shell")
Not very elegant, but I have even created a small loop that displays text options in the console. Can then interact with your program and sheet from there. Clever and more elegant way would be to have your script poll an excel cell and then take action form there.
Something else that you might find nice is that it also also you to run Ipython instead of the default python shell. Cannot imagine using python without Ipython... so you get benefits of tab completion Ipython debugging etc. To activate that just click the "Use Ipython" Checkbox in DataNitro Settings (don't know if this is version dependent).

Python: Redirect output to several consoles?

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.

Robustly killing Windows programs stuck reporting 'problems'

I am looking for a means to kill a Windows exe program that, when being tested from a python script, crashes and presents a dialog to the user; as this program is invoked many times, and may crash repeatedly, this is not suitable.
The problem dialog is the standard reporting of a Windows error:
"Foo.exe has encountered a problem and needs to close. We are sorry for the inconvenience"
and offers a Debug, Send Error Report, and Don't Send buttons.
I am able to kill other forms of dialog resulting from crashes (e.g. a Debug build's assert failure dialog is OK.)
I have tried taskkill.exe, pskill, and the terminate() function on the Popen object from the subprocess module that was used to invoke the .exe
Has anyone encountered this specific issue, and found a resolution?
I expect automating user input to select the window, and press the "Don't Send" button is one possible solution, but I would like something far simpler if possible
Wouldn't it be easier to disable the error reporting feature?
If you were to use CreateProcessEx or a WinAPI specific function, you might be able to call TerminateProcess or TerminateThread to forcibly end the process.

Categories

Resources