Controlling a Windows Console App w/ stdin pipe - python

I am trying to control a console application (JTAG app from Segger) from Python using the subprocess module. The application behaves correctly for stdout, but stdin doesn't seem to be read. If enable the shell, I can type into the input and control the application, but I need to do this programmatically. The same code works fine for issuing commands to something like cmd.exe.
I'm guessing that the keyboard is being read directly instead of stdin. Any ideas how I can send the application input?
from subprocess import Popen, PIPE, STDOUT
jtag = Popen('"C:/Program Files/SEGGER/JLinkARM_V402e/JLink.exe"', shell=True,
universal_newlines=True,
stdin=PIPE,
stdout=PIPE,
stderr=STDOUT)
jtag.stdin.write('usb\n')
jtag.stdin.flush()
print "Stdout:"
while True:
s = jtag.stdout.readline()
if not s:
break
print s,
jtag.terminate()

As shoosh says, I'd try to verify that the application really is looking for keyboard input. If it is, you can try Win32 message passing, or sending it keyboard input via automation.
For the message passing route, you could use the EnumWindows function via ctypes to find the window you're after, then using PostMessage to send it WM_KEYDOWN messages.
You can also send keyboard input via pywinauto, or the ActiveX control of AutoIt via win32com.
Using AutoIt:
from win32com.client import Dispatch
auto = Dispatch("AutoItX3.Control")
auto.WinActivate("The window's title", "")
auto.WinWaitActive("The window's title", "", 10)
auto.Send("The input")

I'm guessing that the keyboard is being read directly instead of stdin
This is a pretty strong assumption and before stitching a solution you should try to verify it somehow. There are different levels of doing this. Actually two I can think of right now:
Waiting for keyboard events from the main windows loop. if this is the case then you can simulate a keyboard simply by sending the window the right kind of message. these can be wither WM_KEYDOWN or WM_CHAR or perhaps some other related variants.
Actually polling the hardware, for instance using GetAsyncKeyState(). This is somewhat unlikely and if this is really what's going on, I doubt you can do anything to simulate it programatically.
Another take on this is trying to use the on-screen keyboard and see if it works with the application. if it does, figure out how to simulate what it does.
Some tools which might be helpful -
Spy++ (comes with Visual Studio) - allows you to see what messages go into a window
strace allows you to see what syscalls a process is making.

Related

How to run a Python script continuously that can receive commands from node

I have set up a Raspberry Pi connected to an LED strip which is controllable from my phone via a Node server I have running on the RasPi. It triggers a simple python script that sets a colour.
I'm looking to expand the functionality such that I have a python script continuously running and I can send colours to it that it will consume the new colour and display both the old and new colour side by side. I.e the python script can receive commands and manage state.
I've looked into whether to use a simple loop or a deamon for this but I don't understand how to both run a script continuously and receive the new commands.
Is it better to keep state in the Node server and keep sending a lot of simple commands to a basic python script or to write a more involved python script that can receive few simpler commands and continuously update the lights?
IIUC, you don't necessarily need to have the python script running continuously. It just needs to store state, and you can do this by writing the state to a file. The script can then just read the last state file at startup, decide what to do from thereon, perform action, then update the state file.
In case you do want to actually run the script continuously though, you need a way to accept the commands. The simplest way for a daemon to accept command is probably through signal, you can use custom signal e.g. SIGUSR1 and SIGUSR2 to send and receive these notifications. These may be sufficient if your daemon only need to accept very simple request.
For more complex request where you need to actually accept messages, you can listen to a Unix socket or listen to a TCP socket. The socket module in the standard library can help you with that. If you want to build a more complex command server, then you may even want to consider running a full HTTP server, though this looks overkill for the current situation.
Is it better to keep state in the Node server and keep sending a lot of simple commands to a basic python script or to write a more involved python script that can receive few simpler commands and continuously update the lights?
There's no straightforward answer to that. It depends on case by case basis, how complex the state is, how frequently you need to change colour, how familiar you are with the languages, etc.
Another option is to have the Node app, calll the Python script as a child process, and pass to it any needed vars, and you can read python's out put as well, like so:
var exec = require('child_process').exec;
var child = exec('python file.py var1 var2', function (error, stdout, stderr) {
}

Python3 - curses input/output over a network socket?

So I've decided to learn Python and after getting a handle on the basic syntax of the language, decided to write a "practice" program that utilizes various modules.
I have a basic curses interface made already, but before I get too far I want to make sure that I can redirect standard input and output over a network connection. In effect, I want to be able to "serve" this curses application over a TCP/IP connection.
Is this possible and if so, how can I redirect the input and output of curses over a network socket?
This probably won't work well. curses has to know what sort of terminal (or terminal emulator, these days) it's talking to, in order to choose the appropriate control characters for working with it. If you simply redirect stdin/stdout, it's going to have no way of knowing what's at the other end of the connection.
The normal way of doing something like this is to leave the program's stdin/stdout alone, and just run it over a remote login. The remote access software (telnet, ssh, or whatever) will take care of identifying the remote terminal type, and letting the program know about it via environment variables.

Python tkinter Capture windows system shutdown

I'm trying to get my tkinter app (python 3.4.2) to be aware of the system shutdown event so it can release the sqlite3 connection and close a log. I found a post from 2009 about using the win32 api module. I can't get the posted sample to work as I expect (I may not understand it), where a message should cause the wndproc function to fire.
2009 reference:
Python - Windows Shutdown Events
Any other good references or pointers to how to accomplish this?
Typically you want to close the connection anytime the app closes, even if it wasn't a normal closure (ie: by picking "Exit" from a menu). The normal way to do that is to set up a handler for the WM_DELETE_WINDOW protocol (something of a dinosaur left over from when tk only worked on X11 systems). I don't know for certain your app will be notified this way when the system shuts down, but it probably does.
For more information see this question on stackoverflow: Intercept Tkinter "Exit" command?

Open a sub-cmd window with Python

I'm making a cmd IRC client in Python. I want to receive data at the same time I can write message, in the previous code I did I could only write 2 messages and then it bugs and I can't write until it receives some kind of data.
The question is, can I have one cmd window running the received data and other one with a constant input waiting for me to write something to send?, maybe with threads?
I've looked through the subprocess library but I don't really know how to code it.
CMD1:
while Connected:
print socket.recv(1024)
CMD2:
while Connected:
text = raw_input("Text to send>> ")
socket.send(text)
(This is a pseudocode not a real one)
This approach you are proposing could be done by making a server like application, and 2 client applications that connect via localhost to send and receive events. So that way you could have 2 terminals open , connected to the same session of the server.
On the other side you should consider a different design approach that include ncurses which allow you to make a terminal ui with input and output at the same terminal (two sections up and down). You can reference: http://gnosis.cx/publish/programming/charming_python_6.html

Is it possible to send "resize pty" command with telnetlib?

I am looking for a way to resize terminal when using telnetlib. I have achieved a similar effect on SSH with Paramiko's resize_pty, but I need to support telnet protocol too. Is this even possible (does telnet even have a control stream)?
Note that telnetlib is not a requirement - if there is a better library I would be happy to use it.
UPDATE (more background): I am building a web-based interface for connecting to networking devices. Frontend is built using JS/AJAX, it basically just sends keystrokes to backend and receives screen content from it. Backend is written in Python and takes care of opening a SSH/telnet session to a device, sends keystrokes to it and fetches an output stream, which is then passed through VT100 virtual terminal (pyte). The contents of virtual screen are then sent back to frontend. The problem arises when user wants to resize the terminal screen size in his browser. With SSH I just send resize_pty() through Paramiko and then also resize the pyte's virtual terminal screen size. But with telnet I was unable to find the appropriate resize function that would tell the device that it should resize its terminal. Is this possible?
Ok, I've been able to assemble the following masterpiece:
naws_command = struct.pack('!BBBHHBB',
255, 250, 31, # IAC SB NAWS
width, height,
255, 240) # IAC SE
t.get_socket().send(naws_command)
Now a few words of explanation.
First of all, telnetlib does not support sending commands directly; it simply escapes them. Thus, to send the command we have to use the underlying socket directly. We do that using the get_socket() method of the Telnet object instance (t here).
The NAWS command assembled here is defined by RFC 1073. The width and height variables are regular Python integers which get packed into two 16-bit unsigned integers.
Note that this isn't a perfect solution and I'm not sure if it will actually work for you. Most importantly, during the capabilities negotiation, telnetlib will inform the server that it WON'T NAWS, so a particular server may actually ignore the commands.
If that's the case, you'd probably have to use set_option_negotiation_callback(). Sadly, that means you will have to handle all the options which normally telnetlib does for you. And AFAIK it has no conveniences for that.

Categories

Resources