how can i make AutoIT send command reliable? - firefox

Hi guys I'm running a script with AutoIt to insert the path of a file to upload with webdriver.
But the send command is so unreliable it's 50/50 it messes up the characters and the script just stops.
Is there a way to make it reliably input the data? Or maybe how can i confirm that the input is correct, resend, and then send?
This is what i have for the code. It sends the input into the firefox upload window.
WinWaitActive("File Upload")
Send("C:\Users\elsid\Desktop\Eclipse\Workspace\NG - Mentored\Autoit\Test.png")
Send("{ENTER}")
Thanks

The most reliable way is to use ControlSetText.
Play with AutoitWindowInfo tool and tweak the script below if needed.
#RequireAdmin ;Will give your script a permission elevation (sometimes its needed)
Opt("WinTitleMatchMode", 1) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
Opt("WinSearchChildren", 1) ;0=no, 1=search children also
WinActivate("File Upload")
WinWaitActive("File Upload","",10)
ControlFocus("File Upload","","Edit1")
Sleep(2000)
ControlSetText("File Upload","","Edit1","dropdowns.jpg")

In my humble opinion, the script stops because it waits that the window will be focused. To not messes up the characters, use function flag 1 in Send().
Try this way:
While WinWait("File Upload","",1) = 0
Sleep(500)
WEnd
WinActivate("File Upload")
Send("C:\Users\elsid\Desktop\Eclipse\Workspace\NG - Mentored\Autoit\Test.png", 1) ;-- flag 1 = keys are sent raw.
Send("{ENTER}")
Good Luck ;)

Related

Pywin32: win32api.SendMessage to a DOS box program not possible?

Is it possible to use win32api.SendMessage to send characters to a program which seems to be running in some sort of DOS box?
In my Windows Task Manager I see a process called ntvdm.exe (apparently that is the "Virtual DOS Machine"). It looks like wowexec.exe (= "windows on windows") and my target.exe are both "inside" that ntvdm.exe, since they have no own PID in the Task Manager. Instead they are shown with an indent below ntvdm.exe.
I have tried to target all possible window handles for my target.exe (from parent = 0 down to every child) via win32api.SendMessage(<mywindowhandle>, win32con.WM_CHAR, 0x41, 0) but the 'A' never arrives in the program. SendMessage works in other programs, such as notepad and notepad++. Only the DOS program is causing me headaches.
Using shell = win32com.client.Dispatch("WScript.Shell") however in combination with shell.AppAcitvate (using the PID of ntvdm.exe) and shell.SendKeys works! Doesn't that send "WM_CHAR" messages in the background as well?
In order to support a myriad of different application types, Windows NT has a fairly complex architecture. You're apparently assuming WM_CHAR messages are keystrokes. This is very much a Win16-way of thinking. The WM stands for Window Message; it's a keystroke event for applications with a window and a message pump.
Console programs on the other hand do not use window message pumps; they have Unix-style Standard In and Standard Out. shell.sendKeys understands the difference.
This also means a console program does not have a window handle. The PID is a process identifier, so not a window handle. A process can have 0, 1 or more window handles, so for every window handle there's a (generally non-unique) PID but not vice versa.
SendKeys works because the shell knows all this.

Is there a way to make an existing cmd window execute commands?

So here is my situtation.
I am using the Windows OS. I am running a Matlab GUI that launches another executable at startup. The other executable runs in batch mode (runs in cmd in the background).
I want to make it so when a user clicks a button on the Matlab GUI, the other executable will run a command and remain open. Is this possible?
NOTE: I do not want to open a new cmd window, I want the existing one to execute commands.
Unfortunately it does not appear that Matlab has the ability you are looking for, at least not directly. I found a post which does explain how to do it with the help of .NET though, which is fortunate since you are on the Windows platform: http://www.mathworks.com/matlabcentral/answers/72356-using-matlab-to-send-strings-to-the-stdin-of-another-console-application
I have copied a lot of this from that post
function lh = task()
% Initialize the process and its StartInfo properties.
% The sort command is a console application that
% reads and sorts text input.
process = System.Diagnostics.Process;
process.StartInfo.FileName = 'sort.exe';
process.EnableRaisingEvents = true;
process.StartInfo.CreateNoWindow = true;
% Set UseShellExecute to false for redirection.
process.StartInfo.UseShellExecute = false;
%Redirect the standard output of the sort command.
process.StartInfo.RedirectStandardOutput = true;
% Set our event handler to asynchronously read the sort output.
lh = process.addlistener('OutputDataReceived',#sortOutputHandler);
% Redirect standard input as well. This stream
% is used synchronously.
process.StartInfo.RedirectStandardInput =true;
% Start the process.
process.Start();
%Use a stream writer to synchronously write the sort input.
ProcessStreamWriter = process.StandardInput;
% Start the asynchronous read of the sort output stream.
process.BeginOutputReadLine();
%Prompt the user for 4 input text lines. Write each
%line to the redirected input stream of the sort command.
numInputLines = 0;
while(numInputLines ~= 4)
inputText = input('Enter a text line (or press the Enter key to stop):', 's');
numInputLines = numInputLines + 1;
if(~isempty(inputText))
ProcessStreamWriter.WriteLine(inputText);
end
end
disp('end of input stream');
%end the inputr stream to the sort command
ProcessStreamWriter.Close();
% wait for the sort process to write the sorted text lines
process.WaitForExit();
process.Close();
end
For handling any output from the CMD you need:
function processOutputHandler(obj,event)
%collect the sort command output and print in command window
if(~isempty(event.Data))
disp(event.Data);
end
end
You can use a stream writer to synchronously write the sort input.
processStreamWriter = process.StandardInput;
Again, I have taken this from the previously mentioned post so I can't take any credit for the code, but I do think it will be able to accomplish what you are looking for. Unfortunately, I am pretty sure this will accomplish what you need. I don't have Matlab on a Windows platform at the moment or I would test this. If you need information on using .NET code in MATLAB (its not immediately clear if you need to add some stuff to establish the .NET interface) MathWorks provides some documentation on it: http://www.mathworks.com/help/matlab/matlab_external/using-net-from-matlab-an-overview.html
Hopefully this helps, or gets you started. Let me know if there's anything else I missed.
You can approach this from the ansys side. Start it with -B-R to read a python script.
From there, you can establish some two-way protocol, for example polling files or, better, by running a web server from python.
Then you can communicate from matlab with that running instance of ansys. If you opt for a web server, you use MATLABs urlread().
Setting up a web-server with python is easy, but you have to learn how to dispatch commands to the hosting ansys application.

How do I check if Windows desktop is locked

Q: In AutoIt, how do I check if Windows desktop is locked
What I have
Let's take this example AutoIt script. It pings an URL in an indefinite loop and reports the response time in a tray tip.
While 1
$responsetime = Ping("www.google.com")
TrayTip("", $responsetime, 1)
sleep(5000)
Wend
Desired result
The new script should only ping if the desktop is not locked. But I haven't found a reliable way to check for this
While 1
$isLocked = secretFunctionIdontKnow
If $isLocked = false Then
Local $responsetime = Ping("www.google.com")
TrayTip("", $responsetime, 1)
EndIf
sleep(5000)
Wend
Hint: The function WinExist("A") seems not reliable enough because a desktop without any open windows will report back 0 (=false) even when unlocked
Based on my comments above, you can use the following secretFunctionIdontKnow ;-)
Func secretFunctionIdontKnow()
$classes = StringSplit(WinGetClassList("[ACTIVE]"), #LF, 2)
Return $classes[0] == "TaskSwitcherWnd"
EndFunc
Fortunately the program switcher hasn't got a return value of TaskSwitcherWnd, so this seems to work for me under Windows 7 Enterprise SP1 64 Bit...
Don't miss the brackets in your function call ;-)

Matlab - signal after command completion

Is there a way to set matlab to come to the foreground of the windows when the command in complete? I can see it happening by executing a dos() but I'm unaware how window management works? Maybe there is a better way? Someone?
Two options. Neither exactly what you are asking for.
Option 1: Open a new figure.
figure();
imagesc(processingDoneSplashImage);
If you want to get fancy, put this in a script, with a timer, and flash the image between bright green, and bright red....
Option 2: My solution to your problem. (I find popping up windows extremely annoying.) I put this function call at the end of my long running scripts, and the computer tells me when it's done processing....
function [ ] = matSpeak( textToSpeak )
%matSpeak takes some text, and outputs onto the speaker the text,
% using the .Net SpeechSynthesizer.
% This only works on Windoze.
if ~exist('textToSpeak','var')
textToSpeak = 'Your processing has completed.';
end
NET.addAssembly('System.Speech');
speak = System.Speech.Synthesis.SpeechSynthesizer;
speak.Volume = 100;
speak.Speak(textToSpeak);
end
Why not just use Growl for your notification windows?
cmd = ['/usr/local/bin/growlnotify -m ' messagestr];
system(cmd);
Of course with Windows you need to fix the path to the growlnotify binary.
Source: http://www.mathworks.com/matlabcentral/newsreader/view_thread/259142
A wrapper with lots of features: Send a notification to Growl on MATLAB Exchange
Many more examples: https://www.google.com/search?q=growl+matlab

how to kill orphaned winword.exe in matlab

Running matlab R2010B on Windows 7 Enterprise
In matlab scripts, I save a bunch of results to a word file and then at the end, close and quit word. The code I use is:
WordFname = ['BatInfoDoc' sprintf('%0.3f',now) '.doc']; % serialnumbered filenames
WordFile = fullfile(pwd,WordFname);
WordApp = actxserver('Word.Application');
WordDoc = WordApp.Documents.Add;
WordDoc.SaveAs2(WordFile);
....
WordApp.Selection.TypeText([title2 title3 title4 title5 title6]);
WordApp.Selection.TypeParagraph;
then finally at the end of the script
WordDoc.Close;
WordApp.Quit;
The problem I have is that through my development process, I often crash the matlab script and wind up leaving orphaned WINWORD.EXE processes, each one of which keeps a lock on the file it had been writing.
Up until now I have been using TaskManager to kill these processes one at a time by hand. Having been developing all morning, I find myself with around 20 files I can't delete because they are locked by about 11 orphaned WINWORD.EXE processes!
My question(s):
1) Is there an elegant way to handle the file writing and saving and closing and so on so I don't lock up files and processes when my script crashes out before I get to the part where I close the file and quit word?
2) Is there an elegant way to determine the bad processes from within matlab script and go through and delete them from within a matlab script? That is, can I code my matlab so it cleans up after itself?
ADDED A FEW MINUTES LATER:
By the way, I would prefer NOT to enclose all my code in a big try-catch and then close the windows after I've caught my error. The problem with this is I do like to go to debug mode on error, and caught errors don't bring me to debug mode.
Straight after you create Wordapp, use c = onCleanup(#()Wordapp.Quit). When your function exits, either naturally or with a crash, c will be deleted and its function will execute, quitting Word. If this is part of a script rather than a function, you can manually delete c to quit.
Also - while developing/debugging, I would set Wordapp.Visible to true so you can manually close word if necessary. Set back to false for production.
Use a handle class to delete them automatically.
classdef SafeWord < handle
properties(Access=public)
WordApp;
end
methods(Access=public)
function this = SafeWord(WordApp)
this.WordApp= WordApp;
end
function delete(this)
this.WordDoc.Close;
this.WordApp.Quit;
end
end
end
And the use case:
sw = SafeWord(Word.Application());
WordApplication = sw.WordApp;
% Do something here
% When sw ends its lifecycle, it calls delete.
Here is a related question.

Resources