94641


標準入力について曖昧な知識しかないため、見当違いな質問をしていたらすみません。。

Pythonの`subprocess`を使用し、子プロセスでキー入力待機（具体的には`msvcrt.getwch()`を使用）を行おうとしています。  
親プロセスではキー入力をエミュレートするため、`Popen.stdin`を介して文字入力をします。

下記のコードを実行したところ、キー入力待機状態でプログラムが止まってしまい、キーボードで物理的にキーを押さないと文字が`print`で出力されませんでした。  
なお、`msvcrt.getwch()`ではなく`sys.stdin.readline()`で待機をすればaが表示されました。

[code]

    import subprocess
    
    # 子プロセスで実行するコマンド
    cmd = ['python', '-c', 'import msvcrt; print(msvcrt.getwch())']
    # cmd = ['python', '-c', 'import sys; print(sys.stdin.readline(1))'] # こちらであれば、aがターミナルに表示された
    
    with subprocess.Popen(cmd, stdin=subprocess.PIPE) as p:
        # 親プロセスからキーを送信する
        key = 'a'  # 送信するキー
        p.stdin.write(key.encode())  # キーをバイト列にエンコードして送信
        p.stdin.flush()  # バッファをフラッシュ
    
[/code]

どのようにプログラムを変更すれば、`msvcrt.getwch()`を使用した上で、キー入力をエミュレートするようなプログラムを実現できますでしょうか。

実行環境はWindows11、Python3.11.3です。


CC BY-SA 4.0
2023-04-24T17:49:31.113
94640
2023-04-25T04:03:31.887
37800
question
python windows
msvcrt.getwch()で待ち受けている子プロセスに対してキー入力をエミュレートする方法


子プロセスとの通信に、標準入出力のリダイレクトを使いたいのか、それともキーボード入力とそのシミュレーションを使いたいのか、どちらが主眼なのかいまひとつ不明ですが。  
`msvcrt.getwch()`を活かす方向で考えるとすれば、[keyboard -
PyPI](https://pypi.org/project/keyboard/) を使ってみてはどうでしょう？ こんな記事があります。  
[Python でキーボード入力をシミュレートする](https://www.delftstack.com/ja/howto/python/python-
simulate-keyboard-input/)

質問記事のプログラムではこんな風に適用出来ます。  
ただし特定のプロセスに向けた方式では無いので該当の子プロセスがキーボードフォーカスを握っていることが前提ですが。

[code]

    import subprocess
    import keyboard
    
    # 子プロセスで実行するコマンド
    cmd = ['python', '-c', 'import msvcrt; print(msvcrt.getwch())']
    
    with subprocess.Popen(cmd, stdin=subprocess.PIPE) as p:
        # 親プロセスからキーを送信する
        keyboard.press_and_release("a")
    
[/code]

あるいは他の手段としてはこんな記事もあるので試してみるのも良いでしょう。  
[【50カウント】Pythonを使ったキー送信 for Windows](https://qiita.com/fukuchan-
senpai/items/369b6e16a526d19a2b73)  
[How to generate keyboard
events?](https://stackoverflow.com/q/13564851/9014308)  
[Python simulate keydown](https://stackoverflow.com/q/11906925/9014308)

ちなみに同じ keyboard モジュールを入力に使用する記事がこちら。  
[Python でキープレスを検出する](https://www.delftstack.com/ja/howto/python/python-detect-
keypress/)

* * *

ちなみにキーボード入力をシミュレートしているかぎり、フォーカスの有無依存からは逃れられない(子プロセス側でフックを使えば出来なくは無いですが複雑になりすぎて新しく作るなら意味が無いでしょう)ですが、こんな記事を参考にウインドウのタイトルをユニークなものに設定しておいて、必要になったらアクティブにするという手段も考えられます。  
それがリーズナブルであるかは少し疑問がありますが、情報として。  
[Windows環境でPythonのシグナルを受け取れない](https://ja.stackoverflow.com/q/62459/26370)


CC BY-SA 4.0
2023-04-24T23:37:45.217
94641
2023-04-25T04:03:31.887
2023-04-25T04:03:31.887
26370
26370
94640
answer