web-dev-qa-db-ja.com

Matlabで.exeファイルを起動した後、プログラムでEnterキーを押します

Matlabでは、Enterキーを押す必要があるポップアップが表示される外部の.exeファイルを開始できます。例えば:

system('C:\Program Files (x86)\WinZip\WINZIP32.EXE')

winzipを起動し、それを使用するには、Enterキーを押して「今すぐ購入」ポップアップウィンドウを通過する必要があります。今、私の問題はwinzipにあるのではなく、例として挙げただけです(とにかくwinrarを使用しています:)。

このような場合、MatlabでプログラムでEnterキーを押すにはどうすればよいですか? (私はwin 7を使用します)

イベントリスナーを使用してそれを解決できますか?

編集:Java.awt.Robotクラスは確かにExplorerで機能しますが、押す必要のあるOKボタンのあるポップアップウィンドウがあるソフトウェアでは機能しません。なぜそれがうまくいかないのか分かりません。誰もが自分のマシンにwinzip/winrarをインストールしていると想定しているので、winzipの例を示しました。私が持っている実際のソフトウェアは異なり、質問とは無関係です。

26
bla

MatlabのJava、具体的には_Java.awt.Robot_クラスを使用する方法があります。 ここ を参照してください。

どうやら、system('...')を使用してMatlabから呼び出されたときの動作方法に関して、2つのタイプのプログラムがあります。

  1. 一部のプログラムでは、Matlabは、プログラムが終了するまで待機してから、次のステートメントを実行します。これは、たとえばWinRARで発生します(少なくとも私のWindows 7マシンでは)。

  2. 他のプログラムの場合、これは発生せず、Matlabは、外部プログラムが開始された直後に次のステートメントを実行します。このタイプの例は、Explorer(標準のWindowsファイルエクスプローラー)です。

これで、タイプ1プログラムの場合でも、すぐに実行をMatlabに戻すことができます。systemに渡された文字列の最後に_&_を追加するだけです。これは Linux Bash Shellの標準 であり、 ここ で説明したように、Windowsでも機能します。

したがって、次のように進めます。

_robot = Java.awt.Robot;
command = '"C:\Program Files (x86)\WinRAR\WinRAR"'; %// external program; full path
system([command ' &']); %// note: ' &' at the end
pause(5) %// allow some time for the external program to start
robot.keyPress (Java.awt.event.KeyEvent.VK_ENTER); %// press "enter" key
robot.keyRelease (Java.awt.event.KeyEvent.VK_ENTER); %// release "enter" key
_
26
Luis Mendo

アプリケーションがWindowsプラットフォームのみにある場合は、_.net_オブジェクトを使用してみてください。

SendWait オブジェクトのSendKeysメソッドを使用すると、次のような「修飾キー」を含む、フォーカスのあるアプリケーションに事実上すべてのキーまたはキーの組み合わせを送信できます。 Alt、 Shift、 Ctrl など.。

最初に行うことは、_.net_ライブラリをインポートしてから、完全な構文をインポートして ENTER キーは次のようになります:

_NET.addAssembly('System.Windows.Forms');
System.Windows.Forms.SendKeys.SendWait('{ENTER}'); %// send the key "ENTER"
_

完全な構文がOKになったときにのみ実行する場合。このコマンドを多用する場合は、匿名のヘルパー機能を使用してください。

メモ帳の小さな例

_%% // import the .NET Assembly and define helper function
NET.addAssembly('System.Windows.Forms');
sendkey = @(strkey) System.Windows.Forms.SendKeys.SendWait(strkey) ;

%% // prepare a few things to send to the notepad
str1 = 'Hello World' ;
str2 = 'OMG ... my notepad is alive' ;
file2save = [pwd '\SelfSaveTest.txt'] ;
if exist(file2save,'file')==2 ; delete(file2save) ; end %// this is just in case you run the test multiple times.

%% // go for it
%// write a few things, save the file then close it.
system('notepad &') ;   %// Start notepad, without matlab waiting for the return value
sendkey(str1)           %// send a full string to the notepad
sendkey('{ENTER}');     %// send the {ENTER} key
sendkey(str2)           %// send another full string to the notepad
sendkey('{! 3}');       %// note how you can REPEAT a key send instruction
sendkey('%(FA)');       %// Send key combination to open the "save as..." dialog
pause(1)                %// little pause to make sure your hard drive is ready before continuing
sendkey(file2save);     %// Send the name (full path) of the file to save to the dialog
sendkey('{ENTER}');     %// validate
pause(3)                %// just wait a bit so you can see you file is now saved (check the titlebar of the notepad)
sendkey('%(FX)');       %// Bye bye ... close the Notepad
_

Microsoftのドキュメントで説明されているように、SendKeysクラスにはタイミングの問題がある場合があるため、複雑な操作を行う場合( Tab 実際に押したいボタンを変更するために複数回)、Matlab呼び出しでpauseSendKeysに導入する必要がある場合があります。

最初に試してはいけませんが、プロセスを同期せずに別のプロセスから管理していることを忘れないでください。そのため、少なくとも複雑なシーケンスの場合は、正しく実行する前に少し試行錯誤する必要があります(単純なものは簡単)。

たとえば上記の私の場合、すべてのデータをECO機能を備えた外付けハードドライブから実行してスタンバイ状態にしているため、「名前を付けて保存...」ダイアログを呼び出すと、 HDDをウェイクアップする必要があるため、表示に時間がかかります。 pause(1)を導入しなかった場合、ファイルパスが不完全になることがありました(パスの最初の部分は、ダイアログにフォーカスが移る前に送信されました)


また、外部プログラムを実行するときは、_&_文字を忘れないでください。それを強調したルイスメンドのすべての功績。 (デフォルトで使用しているため、その重要性を忘れがちです。プログラムからの戻り値を特に待つ必要がある場合にのみ省略します。それ以外の場合は、 単独で実行させます


特殊文字には特別なコードがあります。ここにいくつかあります:

_Shift          +
Control (Ctrl)  ^
Alt            %

Tab            {TAB}
Backspace      {BACKSPACE}, {BS}, or {BKSP}
Validation     {ENTER} or ~ (a tilde)
Ins Or Insert  {INSERT} or {INS}
Delete         {DELETE} or {DEL}

Text Navigation {HOME} {END} {PGDN} {PGUP}
Arrow Keys      {UP} {RIGHT} {DOWN} {LEFT}

Escape          {ESC}
Function Keys   {F1} ... {F16}
Print Screen    {PRTSC}
Break           {BREAK}
_

Microsoftからの完全なリストは見つけることができます ここ

13
Hoki

完全なDOSリダイレクトを許可するコンテキストでコンソールのみのプログラムを実行する必要がある場合は、キャリッジリターンを含むCR.txtというファイルを作成し、「<」表記を使用して値をプログラムにパイプできます。

これは、すべてのキーボード入力をファイルに記録できる場合にのみ機能します。入力が応答に基づいて変化する必要がある場合、それは陰気に失敗します。

別の方法は、プログラムの入力(および場合によっては出力)ストリームを複製してから、データをプログラムにパイプしたり、プログラムからパイプしたりすることです。これはより堅牢で、データへの動的な応答を可能にしますが、ロボットユーザーをアプリケーションに実装するにはかなりの労力が必要になる可能性があります。

Rog-O-Matic は、画面出力を監視し、キーボード入力をシミュレートして初期(1980年代)に再生するプログラムによって完全に制御される大規模なアプリケーションの例ですASCIIグラフィックアドベンチャーゲーム。

GUIベースのアプリケーションでは、他の応答が必要になります。

3
Pekka

Windowsjavascriptインタープリターでこのようなキーストロークをシミュレートする小さなjavascriptユーティリティがあります。

次のコードでjsファイルを作成するだけです。

var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.SendKeys(WScript.Arguments(0));

次に、次のように必要なタイムアウト後にMatlabから呼び出します。

system('c:\my\js\file\script.js {Enter}');

現在ここでテストすることはできませんが、これでうまくいくと思います...

3

Pythonパッケージ pywinauto ダイアログを待って、ボタンを自動的にクリックできます。ただし、ネイティブおよび一部の.NETアプリケーションでのみ使用できます。 WPFボタンを押すのに問題があるかもしれません(多分QTボタンはクリック可能です-チェックされていません)が、そのような場合はapp.DialogTitle.wait('ready').set_focus(); app.DialogTitle.type_keys('{ENTER}')のようなコードが役立つかもしれません。あなたのケースは非常に単純で、おそらくpywinautoのいくつかのトリックで十分です。 「ポップアップ付きアプリ」は64ビットですか32ビットですか。

waitおよびwait_not関数にはtimeoutパラメーターがあります。ただし、ポップアップを待機する無限ループの可能性があるリスナーが正確に必要な場合は、グローバルWindowsフックが適切な方向です( pyHook はマウスイベントとkeybdイベントをリッスンできますが、ダイアログの開始をリッスンできません)。新しいウィンドウを検出できるプロトタイプを見つけようとします。 UIオートメーションAPIイベントハンドラーを使用します...そして...操作... IronPythonが必要です。標準のCPythonからCOMインターフェイスを使用してUIオートメーションハンドラーを設定する方法がまだわかりません。


編集(2019年1月):新しいモジュールwin32hooksは少し前にpywinautoに実装されました。使用例は次のとおりです: examples/hook_and_listen.py

2
Vasily Ryabov