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

时间:2009-04-06 22:01:26

标签: python windows command-line subprocess jtag

我正在尝试使用子进程模块从Python控制控制台应用程序(来自Segger的JTAG应用程序)。应用程序对stdout的行为正确,但似乎没有读取stdin。如果启用shell,我可以键入输入并控制应用程序,但我需要以编程方式执行此操作。相同的代码适用于向cmd.exe等命令发出命令。

我猜测是直接读取键盘而不是stdin。我有什么想法可以发送应用程序输入吗?

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()

2 个答案:

答案 0 :(得分:3)

正如shoosh所说,我试图验证应用程序是否真的在寻找键盘输入。如果是,您可以尝试Win32消息传递,或通过自动化发送键盘输入。

对于消息传递路由,您可以通过ctypes使用EnumWindows函数找到您正在使用的窗口,然后使用PostMessage向其发送WM_KEYDOWN消息。

您也可以通过pywinauto发送键盘输入,或通过win32com发送AutoIt的ActiveX控件。

使用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")

答案 1 :(得分:2)

I'm guessing that the keyboard is being read directly instead of stdin

这是一个非常强大的假设,在缝合解决方案之前,您应该尝试以某种方式验证它。这样做有不同的层次。实际上我现在可以想到两个:

  • 等待主窗口循环中的键盘事件。如果是这种情况,那么只需向窗口发送正确的消息即可模拟键盘。这些可以是WM_KEYDOWNWM_CHAR或者其他一些相关变体。
  • 实际轮询硬件,例如使用GetAsyncKeyState()。这有点不太可能,如果这真的发生了什么,我怀疑你可以做任何事情以编程方式来模拟它。

另一种观点是尝试使用屏幕键盘并查看它是否适用于该应用程序。如果是的话,弄清楚如何模拟它的作用。

一些可能有用的工具 -

  • Spy ++(随Visual Studio一起提供) - 允许您查看哪些消息进入窗口
  • strace允许您查看进程正在进行的系统调用。