Sign in to follow this  
Followers 0
WhyTea

How to drive a command line program?

21 posts in this topic

I've just discovered Autoit. I need to use

it to automate a test tool that is command

line based. The requirement is simple:

1) Autoit to launch the test program

2) Autoit to detect the prompt and send

commands accordingly

3) Check printouts to decide what

to do next

4) Repeat 1)

I'm familiar with Expect in the Unix world.

I would appreciate if someone can show me

some code samples. Thanks for any help and

suggestions.

/Why Tea

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I've just discovered Autoit. I need to use

it to automate a test tool that is command

line based. The requirement is simple:

1) Autoit to launch the test program

2) Autoit to detect the prompt and send

commands accordingly

3) Check printouts to decide what

to do next

4) Repeat 1)

I'm familiar with Expect in the Unix world.

I would appreciate if someone can show me

some code samples. Thanks for any help and

suggestions.

/Why Tea

Hi,

have a look at helpfile for:

Run, StdOut, StdIn, StringInStr, While...WEnd

This gives you a clue for starting. If you have any further problems, post it. If you have code post ist as well.

;-))

Stefan

Edited by 99ojo

Share this post


Link to post
Share on other sites

Hi,

have a look at helpfile for:

Run, StdOut, StdIn, StringInStr, While...WEnd

This gives you a clue for starting. If you have any further problems, post it. If you have code post ist as well.

;-))

Stefan

Thanks Stefan. I had a look at those topics you suggested before my first post. But I couldn't really follow it. It would be nice to be able to see some working samples that make use of the Stdin/out/err. The pattern matching on stdout/err will be particularly useful to me.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thanks Stefan. I had a look at those topics you suggested before my first post. But I couldn't really follow it. It would be nice to be able to see some working samples that make use of the Stdin/out/err. The pattern matching on stdout/err will be particularly useful to me.

Hi,

example for batch file. Save it as c:\test.cmd

CMD File:

@echo off
REM Input Drive Letter
set /p lw=Drive: 

REM Input Name
set /p nn=Name: 

echo %lw%> c:\test.txt
echo %nn%>> c:\test.txt
notepad c:\test.txt

Now AutoIT Code for STDIn and Out:

#include <Constants.au3>

Local $foo = Run(@ComSpec & " /c " & "c:\test.cmd","", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)

Local $data
While True
    $data = StdoutRead ($foo)
    If @error Then ExitLoop
    If StringInStr ($data, "Drive") <> 0 Then ;waiting for CMD Input Drive Letter
        MsgBox (0,"Drive", $data)
        StdinWrite ($foo, "E:" & @CR)
    ElseIf StringInStr ($data, "Name") <> 0 Then ;waiting for CMD Input Name
        MsgBox (0,"Name", $data)
        StdinWrite ($foo, "Harry Hirsch" & @CR)
    EndIf
    Sleep(25)
WEnd

or

#include <Constants.au3>

Local $foo = Run(@ComSpec & " /c " & "c:\test.cmd","", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)

Local $data
While True
    $data = StdoutRead ($foo)
    If @error Then ExitLoop
    Switch $data
        Case "Drive: "
            StdinWrite ($foo, "E:" & @CR)
        Case "Name: "
            StdinWrite ($foo, "Harry Hirsch" & @CR)
    EndSwitch
    Sleep(25)
WEnd

;-))

Stefan

Edited by 99ojo

Share this post


Link to post
Share on other sites

Thanks Stefan for such nice examples. Now I can go away and start Autoit-scripting...

/Why Tea

Share this post


Link to post
Share on other sites

Hi,

example for batch file. Save it as c:\test.cmd

CMD File:

@echo off
REM Input Drive Letter
set /p lw=Drive: 

REM Input Name
set /p nn=Name: 

echo %lw%> c:\test.txt
echo %nn%>> c:\test.txt
notepad c:\test.txt

Now AutoIT Code for STDIn and Out:

#include <Constants.au3>

Local $foo = Run(@ComSpec & " /c " & "c:\test.cmd","", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)

Local $data
While True
    $data = StdoutRead ($foo)
    If @error Then ExitLoop
    If StringInStr ($data, "Drive") <> 0 Then ;waiting for CMD Input Drive Letter
        MsgBox (0,"Drive", $data)
        StdinWrite ($foo, "E:" & @CR)
    ElseIf StringInStr ($data, "Name") <> 0 Then ;waiting for CMD Input Name
        MsgBox (0,"Name", $data)
        StdinWrite ($foo, "Harry Hirsch" & @CR)
    EndIf
    Sleep(25)
WEnd

or

#include <Constants.au3>

Local $foo = Run(@ComSpec & " /c " & "c:\test.cmd","", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)

Local $data
While True
    $data = StdoutRead ($foo)
    If @error Then ExitLoop
    Switch $data
        Case "Drive: "
            StdinWrite ($foo, "E:" & @CR)
        Case "Name: "
            StdinWrite ($foo, "Harry Hirsch" & @CR)
    EndSwitch
    Sleep(25)
WEnd

;-))

Stefan

Stefan,

Is there a way to clear the buffer that holds

the stdout data? As I need to control a command

line program for some repetitive tests, the same

text patterns may occur many times over. After

finding the first occurrence, it would be nice

to clear the buffer. It's the default behavior

of Expect, which I hope to emulate in Autoit.

/Why Tea

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Is there a way to clear the buffer that holds

the stdout data? As I need to control a command

line program for some repetitive tests, the same

text patterns may occur many times over. After

finding the first occurrence, it would be nice

to clear the buffer. It's the default behavior

of Expect, which I hope to emulate in Autoit.

/Why Tea

To clear the buffer, simply call the StdOutRead function and ignore the output. This clears the internal buffer AutoIt uses.

Func StdOutClearBuffer()
   StdOutRead($foo)
EndFunc
Edited by Manadar

Share this post


Link to post
Share on other sites

To clear the buffer, simply call the StdOutRead function and ignore the output. This clears the internal buffer AutoIt uses.

Func StdOutClearBuffer()
   StdOutRead($foo)
EndFunc

That's simple :D Thanks!

I tried Stefan's code on Win Server 2003 and

it worked fine. But when I tried to use the

same technique to run my test program, StdoutRead()

returns nothing. I'll list the code below.

This doesn't work ("Test Failed!" is always returned

with $data containing nothing. Also, nothing shows up

in the cmd window):

#include <Constants.au3>

Local $cnt, result=0

Local $my_prog = "c:\somewhere\bin\my_prog.exe"

Local $pid = Run(@ComSpec & " /k " & $my_prog,"", @SW_SHOW, $STDIN_CHILD + $STDOUT_CHILD + STDERR_CHILD)

Sleep(50)

StdinWrite ($pid, "C") ; no CR needed

Sleep(50)

StdinWrite ($pid, "M") ; no CR needed

StdinWrite ($pid, "S") ; no CR needed

Sleep(50)

StdinWrite ($pid, "0{ENTER}1{ENTER}1{ENTER}2{Enter}")

Sleep(200)

MsgBox (0,"Test data sent", "Waiting for results")

$cnt = 1

While True

$data = StdoutRead ($pid)

If @error Then ExitLoop

If StringInStr ($data, "<009>") <> 0 Then

$result = 1

MsgBox (0,"Test Passed!", $data)

ExitLoop

EndIf

Sleep(30)

$cnt = $cnt + 1

If $cnt == 500 Then

ExitLoop ; timeout

EndIf

WEnd

StdinWrite ($pid, "QCQ") ; no CR needed

If $result == 0 Then

MsgBox (0,"Test Failed!", $data)

EndIf

Th code below runs the test program correctly without

using STDIN/OUT. I was able to see $my_prog printed a

lot of text in the cmd window.

#include <Constants.au3>

Local $my_prog = "c:\somewhere\bin\my_prog.exe"

Local $pid = Run(@ComSpec & " /k " & $my_prog)

Sleep(100)

Send ("C")

Sleep(50)

Send ("MS")

Sleep(100)

Send ("0{ENTER}1{ENTER}1{ENTER}2{Enter}")

What did I do wrong?

/Why Tea

Share this post


Link to post
Share on other sites

StdinWrite ($pid, "0{ENTER}1{ENTER}1{ENTER}2{Enter}")

This doesn't work. Do this instead:

StdinWrite ($pid, "0" & @LF & "1" & @LF & "1" & @LF & "2" & @LF)

Tried. But result was the same. $data contained nothing.

Share this post


Link to post
Share on other sites

Tried. But result was the same. $data contained nothing.

Hi,

try instead of @LF @CR

;-))

Stefan

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Hi,

try instead of @LF @CR

;-))

Stefan

Or both, @CRLF.. I'm looking at the rest of your script now, this was the first thing that I saw that wasn't correct and thought it might fix the problem you had.

Edit: Try this for debugging:

$cnt = 1
While True
    $data = StdoutRead ($pid)
    ConsoleWrite($data) ; Puts the output data into the SciTE console window. Useful for debugging.

    If @error Then ExitLoop

    If StringInStr ($data, "<009>") <> 0 Then
        $result = 1
        MsgBox (0,"Test Passed!", $data)
        ExitLoop
    EndIf
    Sleep(30)
    $cnt = $cnt + 1
    If $cnt == 500 Then
        ExitLoop ; timeout
    EndIf
WEnd
Edited by Manadar

Share this post


Link to post
Share on other sites

Or both, @CRLF.. I'm looking at the rest of your script now, this was the first thing that I saw that wasn't correct and thought it might fix the problem you had.

Edit: Try this for debugging:

$cnt = 1
While True
    $data = StdoutRead ($pid)
    ConsoleWrite($data) ; Puts the output data into the SciTE console window. Useful for debugging.

    If @error Then ExitLoop

    If StringInStr ($data, "<009>") <> 0 Then
        $result = 1
        MsgBox (0,"Test Passed!", $data)
        ExitLoop
    EndIf
    Sleep(30)
    $cnt = $cnt + 1
    If $cnt == 500 Then
        ExitLoop ; timeout
    EndIf
WEnd

I know it has to be @CR since I could manually

enter the sequence with ^M, which is a CR 0r

0xD. However, ConsoleWrite() also failed to

display anything in the SciTE console window.

Does it mean that none of the StdinWrite()

actually goes to the application? Are there

anymore debugging tricks I can use?

Share this post


Link to post
Share on other sites

I know it has to be @CR since I could manually

enter the sequence with ^M, which is a CR 0r

0xD. However, ConsoleWrite() also failed to

display anything in the SciTE console window.

Does it mean that none of the StdinWrite()

actually goes to the application? Are there

anymore debugging tricks I can use?

I have put Sleep()/ConsoleWrite() at various places

after Run(), but nothing showed up. The program

displays quite a few lines of text immediately

after launch with various input options. So I should

at least get something.

I need some ideas to go on, please help!

/Why Tea

Share this post


Link to post
Share on other sites

I have put Sleep()/ConsoleWrite() at various places

after Run(), but nothing showed up. The program

displays quite a few lines of text immediately

after launch with various input options. So I should

at least get something.

I need some ideas to go on, please help!

/Why Tea

Hi,

that sounds like a serious problem.

ConsoleWrite() at various places

after Run(), but nothing showed up

-> That means you don't get any data from STDOUT.

If i test my code for the test.cmd with a consolewrite the data is written to AutoIT Console, but i see nothing in the command box.

Maybe you should add the @CRLF to your ConsoleWriteCommand, see my code.

Also you should have a look in the documentation of your program, if standard stdout is used.

It seems that your application opens an own consolewindow with a seperate STDIO Stream.

;-((

Stefan

Share this post


Link to post
Share on other sites

Hi,

that sounds like a serious problem.

-> That means you don't get any data from STDOUT.

If i test my code for the test.cmd with a consolewrite the data is written to AutoIT Console, but i see nothing in the command box.

Maybe you should add the @CRLF to your ConsoleWriteCommand, see my code.

Also you should have a look in the documentation of your program, if standard stdout is used.

It seems that your application opens an own consolewindow with a seperate STDIO Stream.

;-((

Stefan

There is a bug in Windows according to: http://support.microsoft.com/default.aspx?kbid=321788. But it didn't make any difference after I added the new registry key. The program simply uses "cout" and printf(), so I doubt the printouts wouldn't go to the stdio. I'm thinking of giving up my original plan of automated testing and just use my simple script to launch the test program with visual inspection of the printouts.

Share this post


Link to post
Share on other sites

There is a bug in Windows according to: http://support.microsoft.com/default.aspx?kbid=321788. But it didn't make any difference after I added the new registry key. The program simply uses "cout" and printf(), so I doubt the printouts wouldn't go to the stdio. I'm thinking of giving up my original plan of automated testing and just use my simple script to launch the test program with visual inspection of the printouts.

Hi,

if you have W2K SP4 you should download the hotfix and install it.

I think a 3 mb file only for changing registry setting is to big.

;-))

Stefan

Share this post


Link to post
Share on other sites

Hi,

if you have W2K SP4 you should download the hotfix and install it.

I think a 3 mb file only for changing registry setting is to big.

;-))

Stefan

I've changed it manually, but it still didn't work :D

Share this post


Link to post
Share on other sites

I've changed it manually, but it still didn't work :D

Hi,

you should install the hotfix, because some windows files are replaced as well.

;-))

Stefan

Share this post


Link to post
Share on other sites

Hi,

you should install the hotfix, because some windows files are replaced as well.

;-))

Stefan

Not too sure about that as I am running on Win 2003 (i.e. Version 5.2.3790) which is not the same as Win2K.

/Why Tea

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0