简体   繁体   English

使用stdin管道控制Windows控制台应用程序

[英]Controlling a Windows Console App w/ stdin pipe

I am trying to control a console application (JTAG app from Segger) from Python using the subprocess module. 我试图使用subprocess模块​​从Python控制控制台应用程序(Segger的JTAG应用程序)。 The application behaves correctly for stdout, but stdin doesn't seem to be read. 该应用程序对stdout的行为正确,但似乎无法读取stdin。 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. 相同的代码可以很好地向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. 正如shoosh所说,我将尝试验证该应用程序确实在寻找键盘输入。 If it is, you can try Win32 message passing, or sending it keyboard input via automation. 如果是这样,则可以尝试传递Win32消息,或者通过自动化将其发送给键盘输入。

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. 对于消息传递路线,您可以通过ctypes使用EnumWindows函数来查找要访问的窗口,然后使用PostMessage将其发送给WM_KEYDOWN消息。

You can also send keyboard input via pywinauto , or the ActiveX control of AutoIt via win32com. 您也可以通过pywinauto发送键盘输入,或通过win32com发送AutoIt的ActiveX控件。

Using AutoIt: 使用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. 这些可以是WM_KEYDOWNWM_CHAR或其他一些相关的变体。
  • Actually polling the hardware, for instance using GetAsyncKeyState() . 实际轮询硬件,例如使用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 Spy ++(Visual Studio附带)-允许您查看进入窗口的消息
  • strace allows you to see what syscalls a process is making. strace允许您查看进程正在执行的系统调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM