如何在Windows上通过Python控制交互式控制台的输入/输出?

亚历克斯·布莱克曼

我需要控制一个Windows程序,该程序通过_kbhit调用直接从控制台读取输入可以在以下位置找到此类程序的示例:https : //stackoverflow.com/a/15603102/365492_getch<conio.h>

在Linux上,我可以pty.openpty()用来创建新的伪终端并模拟按键。参见以下示例:https : //code.google.com/p/lilykde/source/browse/trunk/lilykde/py/runpty.py

在Windows上,我尝试写入CONIN$/,CONOUT$但我只能看到我的数据显示在控制台上,而子进程则忽略它。

这是代码:

#!/usr/bin/env python

import subprocess
import time

TEST_EXECUTABLE = 'C:\\dev\\test.exe'
TEST_INPUT = 'C:\\dev\\input.txt'


def main():
    with open(TEST_INPUT, mode='r') as test_input, open('CONOUT$', mode='wb') as conout:
        test_exec = subprocess.Popen([TEST_EXECUTABLE],
                                     bufsize=0,
                                     stdin=None,
                                     stdout=None,
                                     stderr=None)

        for cmd in test_input:
            cmd = cmd.strip('\r\n')
            conout.write(cmd)
            conout.flush()
            time.sleep(1)

        ret = test_exec.wait()
        print '%s (%d): %d' % (TEST_EXECUTABLE, test_exec.pid, ret)

    pass

if __name__ == "__main__":
    main()

有可能吗?如何模拟用户与子进程的交互?

谢谢。亚历克斯

亚历克斯·布莱克曼

我找到了答案。不幸的是,没有内置模块可以执行此操作,因此我不得不使用ctypesWin32 API来完成此操作。这是代码:

#!/usr/bin/env python

from ctypes import *
import msvcrt
import os
import subprocess
import time

TEST_EXECUTABLE = 'C:\\dev\\test.exe'
TEST_INPUT = 'C:\\dev\\input.txt'

# input event types
KEY_EVENT = 0x0001

# constants, flags
MAPVK_VK_TO_VSC = 0

# structures
class CHAR_UNION(Union):
    _fields_ = [("UnicodeChar", c_wchar),
                ("AsciiChar", c_char)]

    def to_str(self):
        return ''


class KEY_EVENT_RECORD(Structure):
    _fields_ = [("bKeyDown", c_byte),
                ("pad2", c_byte),
                ("pad1", c_short),
                ("wRepeatCount", c_short),
                ("wVirtualKeyCode", c_short),
                ("wVirtualScanCode", c_short),
                ("uChar", CHAR_UNION),
                ("dwControlKeyState", c_int)]

    def to_str(self):
        return ''


class INPUT_UNION(Union):
    _fields_ = [("KeyEvent", KEY_EVENT_RECORD)]

    def to_str(self):
        return ''


class INPUT_RECORD(Structure):
    _fields_ = [("EventType", c_short),
                ("Event", INPUT_UNION)]

    def to_str(self):
        return ''


def write_key_to_console(hcon, key):
    li = INPUT_RECORD * 2
    list_input = li()

    ke = KEY_EVENT_RECORD()
    ke.bKeyDown = c_byte(1)
    ke.wRepeatCount = c_short(1)

    cnum = ord(key)
    ke.wVirtualKeyCode = windll.user32.VkKeyScanW(cnum)
    ke.wVirtualScanCode = c_short(windll.user32.MapVirtualKeyW(int(cnum),
                                                               MAPVK_VK_TO_VSC))
    ke.uChar.UnicodeChar = unichr(cnum)
    kc = INPUT_RECORD(KEY_EVENT)
    kc.Event.KeyEvent = ke
    list_input[0] = kc

    list_input[1] = list_input[0]
    list_input[1].Event.KeyEvent.bKeyDown = c_byte(0)

    events_written = c_int()
    ret = windll.kernel32.WriteConsoleInputW(hcon,
                                             list_input,
                                             2,
                                             byref(events_written))

    return ret


def main():
    with open(TEST_INPUT, mode='r') as test_input:
        fdcon = os.open('CONIN$', os.O_RDWR | os.O_BINARY)
        hconin = msvcrt.get_osfhandle(fdcon)

        test_exec = subprocess.Popen([TEST_EXECUTABLE])

        for cmd in test_input:
            cmd = cmd.strip('\r\n')
            write_key_to_console(hconin, cmd)
            time.sleep(1)

        os.close(fdcon)
        ret = test_exec.wait()

        print '%s (%d): %d' % (TEST_EXECUTABLE, test_exec.pid, ret)

    pass


if __name__ == "__main__":
    main()

input.txt文件每行包含一个字符。write_key_to_console可以轻松扩展该功能,一次写入多个字符。

如果调用进程没有控制台,或者其控制台与子进程之一不同,那么AttachConsole在打开CONIN$文件之前,我们需要以子进程ID作为参数来调用函数

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Windows上通过Python控制交互式控制台的输入/输出?

来自分类Dev

如何在Python中自动执行交互式控制台应用程序?

来自分类Dev

如何在PyDev Eclipse中以调试模式隐藏交互式控制台?

来自分类Dev

如何基于块而不是行制作python交互式控制台

来自分类Dev

将Kafka Stream输入输出到控制台?

来自分类Dev

如何将输出从交互式Perl脚本重定向到文件和控制台?

来自分类Dev

如何在python交互式控制台中捕获“ Ctrl-D”?

来自分类Dev

Pydev 交互式控制台 - 使用“if”时不出现输出

来自分类Dev

Pycharm交互式控制台不起作用

来自分类Dev

有ABAP交互式控制台吗?

来自分类Dev

PyDev交互式控制台问题

来自分类Dev

QML交互式控制台小部件

来自分类Dev

控制台的交互式/可视合并工具?

来自分类Dev

telnetlib-交互式控制台与脚本

来自分类Dev

HiDPI 控制台字体非交互式

来自分类Dev

Eclipse上的PyDev Jython交互式控制台无法创建

来自分类Dev

在 sublime 3 控制台上输出交互式程序

来自分类Dev

交互式控制台/ Pydev控制台由于未处理的错误而完全中断

来自分类Dev

如何向Atom添加实时(交互式)控制台窗口?

来自分类Dev

如何使用Node JS创建交互式控制台界面?

来自分类Dev

在交互式故事场景中,如何清除控制台并执行特定的代码块

来自分类Dev

从脚本运行交互式Python控制台时键盘快捷键损坏

来自分类Dev

交互式Python控制台与Django的“ manage.py shell”之间的区别

来自分类Dev

与来自不同进程的正在运行的交互式控制台程序进行交互

来自分类Dev

如何在python中获取URL的控制台输出?

来自分类Dev

在Windows的IEx(交互式Elixir控制台)中启用UTF8字符

来自分类Dev

立即将用户输入输出到控制台

来自分类Dev

运行测试时将鼻子或pytest插入交互式控制台

来自分类Dev

Google App Engine交互式控制台:ImportError:没有名为模型的模块

Related 相关文章

  1. 1

    如何在Windows上通过Python控制交互式控制台的输入/输出?

  2. 2

    如何在Python中自动执行交互式控制台应用程序?

  3. 3

    如何在PyDev Eclipse中以调试模式隐藏交互式控制台?

  4. 4

    如何基于块而不是行制作python交互式控制台

  5. 5

    将Kafka Stream输入输出到控制台?

  6. 6

    如何将输出从交互式Perl脚本重定向到文件和控制台?

  7. 7

    如何在python交互式控制台中捕获“ Ctrl-D”?

  8. 8

    Pydev 交互式控制台 - 使用“if”时不出现输出

  9. 9

    Pycharm交互式控制台不起作用

  10. 10

    有ABAP交互式控制台吗?

  11. 11

    PyDev交互式控制台问题

  12. 12

    QML交互式控制台小部件

  13. 13

    控制台的交互式/可视合并工具?

  14. 14

    telnetlib-交互式控制台与脚本

  15. 15

    HiDPI 控制台字体非交互式

  16. 16

    Eclipse上的PyDev Jython交互式控制台无法创建

  17. 17

    在 sublime 3 控制台上输出交互式程序

  18. 18

    交互式控制台/ Pydev控制台由于未处理的错误而完全中断

  19. 19

    如何向Atom添加实时(交互式)控制台窗口?

  20. 20

    如何使用Node JS创建交互式控制台界面?

  21. 21

    在交互式故事场景中,如何清除控制台并执行特定的代码块

  22. 22

    从脚本运行交互式Python控制台时键盘快捷键损坏

  23. 23

    交互式Python控制台与Django的“ manage.py shell”之间的区别

  24. 24

    与来自不同进程的正在运行的交互式控制台程序进行交互

  25. 25

    如何在python中获取URL的控制台输出?

  26. 26

    在Windows的IEx(交互式Elixir控制台)中启用UTF8字符

  27. 27

    立即将用户输入输出到控制台

  28. 28

    运行测试时将鼻子或pytest插入交互式控制台

  29. 29

    Google App Engine交互式控制台:ImportError:没有名为模型的模块

热门标签

归档