我有一个使用dos命令打开exe的Matlab脚本。这个exe暂停等待用户输入。对于这个项目,我需要编写脚本和动态的所有内容,因此matlab必须能够继续运行其脚本,动态确定输入到正在运行的exe的内容,然后输入它。
到目前为止,我已经能够让exe在后台运行并让matlab脚本继续使用dos('test.exe &')
,但是我无法得到matlab来向运行的exe发送输入。我已经尝试过批处理文件,但我仍遇到同样的问题,当cmd行exe运行暂停等待用户输入时,如何自动将输入发送到cmd行?
我最好的猜测是我需要将matlab的标准输出重新路由到特定的,已经打开的cmd实例的标准输入,但是我不知道怎么做到目前为止找不到任何东西在网上。非常感谢任何见解,谢谢。
答案 0 :(得分:1)
有一种方法。它只是不优雅。
当您使用&
调用程序时,其窗口将显示在前景中并具有焦点(至少在我的系统上)。因此,您可以使用java.awt.Robot
类从Matlab发送键盘事件。
如果您需要自动化从字符到按键的转换,您可能需要一个很大的switch
语句along these lines。以下示例手动定义事件,仅适用于小输入。
robot = java.awt.Robot;
dos('copy con &'); % open MS-DOS Window that will just echo the input text
pause(1) % allow some time for the external program to start up
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_H);
robot.keyRelease(java.awt.event.KeyEvent.VK_H);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_E);
robot.keyRelease(java.awt.event.KeyEvent.VK_E);
robot.keyPress(java.awt.event.KeyEvent.VK_L);
robot.keyRelease(java.awt.event.KeyEvent.VK_L);
robot.keyPress(java.awt.event.KeyEvent.VK_L);
robot.keyRelease(java.awt.event.KeyEvent.VK_L);
robot.keyPress(java.awt.event.KeyEvent.VK_O);
robot.keyRelease(java.awt.event.KeyEvent.VK_O);
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_1);
robot.keyRelease(java.awt.event.KeyEvent.VK_1);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_ENTER);
robot.keyRelease(java.awt.event.KeyEvent.VK_ENTER);
以下是一个示例运行:
答案 1 :(得分:0)
不幸的是,没有办法做你所描述的。
外部程序暂停并等待输入的事实是一个严峻的挑战:对于Matlab,只有一个程序在后台运行,它无法“知道”该程序正在等待输入在某一特定时刻。
然后,另一个问题是没有“Matlabish”方法将命令发送到后台运行的线程发送。 编辑路易斯提出的解决方案很丑陋但适用于此。
如果您可以修改外部程序,那么您可以通过为输入传输定义不同的协议(如TCP / IP)来避免此问题。但这不是一般答案,我猜你没有这种可能性。
如果您真的绝望,可以尝试使用Sikuli。
答案 2 :(得分:0)
感谢Luis Mendo的精彩解释,我已经快速整理了一个函数,它接受一个字符串输入并输出正确的机器人命令。这个对我有用!
function typeStringOut(robot,text)
keyMatch = {};
keyMatch(1,:) = {'`','-','=',',','.','/',';','[',']','\'};
keyMatch(2,:) = {'~','_','+','<','>','?',':','{','}','|'};
keyMatch(3,:) = {'BACK_QUOTE','MINUS','EQUALS','COMMA','PERIOD','SLASH','SEMICOLON','OPEN_BRACKET','CLOSE_BRACKET','BACK_SLASH'};
numKeyMatch = {};
numKeyMatch(1,:) = {'1','2','3','4','5','6','7','8','9','0'};
numKeyMatch(2,:) = {'!','@','#','$','%','^','&','*','(',')'};
for i=1:length(text)
if isstrprop(text(i),'alpha')
if isstrprop(text(i),'upper')
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
end
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',upper(text(i)),');']);
if isstrprop(text(i),'upper')
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
end
elseif isstrprop(text(i),'digit')
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',text(i),');']);
elseif isstrprop(text(i),'wspace')&&strcmp(text(i),' ')
eval('robot.keyPress(java.awt.event.KeyEvent.VK_SPACE);');
elseif isstrprop(text(i),'punct')||isstrprop(text(i),'graphic')
switch text(i)
case {'`','-','=',',','.','/',';','[',']','\'}
matchIdx = strcmp(keyMatch(1,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{3,matchIdx},');']);
case {'~','_','+','<','>','?',':','{','}','|'}
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(keyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{3,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
case {'!','@','#','$','%','^','&','*','(',')'}
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(numKeyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',numKeyMatch{3,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
otherwise
error([text(i),' is unknown character']);
end
elseif strcmp(text(i),'<')||strcmp(text(i),'>')
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(keyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{1,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
else
error([text(i),' is unknown character']);
end
end
robot.keyPress(java.awt.event.KeyEvent.VK_ENTER);
robot.keyRelease(java.awt.event.KeyEvent.VK_ENTER);
end