在Matlab中启动.exe文件后,以编程方式按Enter键
在Matlab中,我可以启动外部.exe文件,有时popup需要按下Enter键。 例如:
system('C:\Program Files (x86)\WinZip\WINZIP32.EXE')
将启动Winzip,然后为了使用它,你需要通过按下回车“立即购买”popup窗口。 现在我的问题不是用winzip,我只是把它作为一个例子(反正我用winrar :)。
在这种情况下,如何以编程方式在Matlab中按下input键? (我用win 7)
一个事件监听器可以用来解决这个问题吗?
编辑:java.awt.Robot类的确可以在浏览器上工作,但是没有任何带有需要按下的确定button的popup窗口的软件。 我不知道为什么它不起作用。 我给了winzip的例子,因为我认为每个人都已经在他们的机器上安装了winzip / winrar。 我所拥有的实际软件是不同的,不相关的问题。
有一种使用来自Matlab的Java的方法,特别是java.awt.Robot
类。 看到这里 。
显然有两种types的程序,关于他们的工作方式,当从system('...')
调用Matlab system('...')
:
-
对于某些程序,Matlab在运行下一个语句之前等待程序结束。 这发生在例如
WinRAR
(至less在我的Windows 7机器上)。 -
对于其他程序,这种情况不会发生,在外部程序启动后,Matlab会继续执行下一个语句。 这种types的例子是
explorer
(标准的Windows文件浏览器)。
现在,即使对于types1的程序,也可以立即将执行返回到Matlab:只需在传递给system
的string的末尾添加&
即可。 这在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
如果您的应用程序只在Windows平台上,您可以尝试使用.net
对象。
SendKeys
对象的SendWait
方法允许发送几乎任何按键或组合键到具有焦点的应用程序,包括诸如Alt , Shift , Ctrl等的“修饰键”。
要做的第一件事是导入.net
库,那么发送ENTER键的完整语法是:
NET.addAssembly('System.Windows.Forms'); System.Windows.Forms.SendKeys.SendWait('{ENTER}'); %// send the key "ENTER"
如果只有完整的语法是可以的, 如果您打算广泛使用该命令,则可以使用匿名帮助函数来帮助自己。
记事本的一个小例子
%% // 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
类有时可能会有一些计时问题,所以如果您想要进行复杂的操作(比如多次selectTab来更改实际想要按下的button),则可能需要在Matlab调用中引入一个pause
SendKeys
。
尽量不要尝试,但是不要忘记你正在pipe理另一个进程而没有进行任何同步,因此在你做出正确的决定之前对所有可能需要一些试验和错误的进行计时,至less对于复杂的序列(简单的应该是直截了当)。
在我上面的例子中,我正在运行一个ECO函数的外部硬盘驱动器的所有数据,它将其置于待机状态,所以当我调用“另存为…”对话框时,需要花费时间来显示,因为硬盘必须唤醒。 如果我没有引入pause(1)
,有时文件path将不完整(path的第一部分在对话框焦点之前发送) 。
此外,执行外部程序时不要忘记&
字符。 所有信贷路易斯门多突出显示它。 (我倾向于忘记它是多么重要,因为我默认使用它,如果我必须特别等待来自程序的返回值,我才会忽略它,否则我让它自己运行 )
特殊字符有一个特殊的代码。 这里有几个:
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}
微软的完整列表可以在这里find
有一个小的JavaScript工具,可以在Windows的JavaScript解释器上模拟这种按键。
用下面的代码创build一个js文件:
var WshShell = WScript.CreateObject("WScript.Shell"); WshShell.SendKeys(WScript.Arguments(0));
然后在这样的必要的超时之后从Matlab调用它:
system('c:\my\js\file\script.js {Enter}');
现在不能在这里testing,但我认为这应该工作…
如果您需要在允许完全DOSredirect的环境中运行仅用于控制台的程序,则可以创build一个名为,例如包含回车符的CR.txt文件,并使用“<”符号将值传递到程序中。
这只有在你能提供所有键盘input的情况下才可以logging在文件中。 如果投入必须根据反应而变化,那么它就会失败。
另一种方法是复制程序的input(可能是输出)stream,然后将数据input和输出程序。 这是更强大的,可以允许dynamic响应数据,但也可能需要大量的努力,实现一个机器人用户的应用程序。
基于GUI的应用程序将需要其他响应。
Python包pywinauto可以等待任何对话框并自动点击button。 但它仅适用于本机和一些.NET应用程序。 你可能有按下WPFbutton的问题(也许QTbutton是可点击 – 没有选中),但在这种情况下代码,如app.DialogTitle.Wait('ready').SetFocus(); app.DialogTitle.TypeKeys('{ENTER}')
app.DialogTitle.Wait('ready').SetFocus(); app.DialogTitle.TypeKeys('{ENTER}')
可能有帮助。 你的情况很简单,可能pywinauto一些技巧就足够了。 是你的“popup式应用程序”64位或32位?
Wait
和WaitNot
函数有超时参数。 但是,如果你需要准确的侦听器和潜在的无限循环等待popup窗口,良好的方向是全局Windows挂钩( pyHook可以听到鼠标和keybd事件,但不能听对话框打开)。 我会尽量find我的原型,可以检测到新的窗口。 它使用UI自动化API事件处理程序…和… ops …它需要IronPython。 我仍然不知道如何设置标准CPython的COM接口的UI自动化处理程序。