Jump to content

Running Dos Programs


Recommended Posts

Jon:

I am posting the following link to MS Technet both as way of saying THANKS for AutoIt and also as a possible resource of anyone who is struggling with automating some really difficult (lots of user inputs and interrupts) DOS in Windows XP. My experience with AutoIt has been simply fantastic, relative to even MSH or WSH. As the moderator on Technet says "AutoIt has once again proved it can do the seemingly impossible"...which in this case happens to be sending the ESC interrupt to an ancient DOS program.

http://www.microsoft.com/technet/community...erver.scripting

Compliments to AutoIt are on Page 2 of this post at 4/11/2006 9:07 PM PST from Alex K. Angelopoulos who helped me quite a bit with this vexing problem.

I still have some "timing" issues unresolved with smpdbk0.au3...it works on my computer but seems to improperly terminate on others...

Also, I would like to suggest the following method...to your list

FindWindow(*title-wildcard*)...although this can easily be a function...as shown in smpdbk0.au3.

In any case, EXCELLENT product...keep it up!

smpdbk1.au3

smpdbk2.au3

smpdbk0.au3

Link to comment
Share on other sites

I'm not a big fan of using Sleeps to wait and send a response to automate. If I can avoid it I do at all costs.

I think a much more elegant approach is to use StdOut Read and Write functions to trigger events in a dos window and send input accordingly.

For example of this, I just wrote a convert.exe automation for a user at:

http://www.autoitscript.com/forum/index.php?showtopic=24702

-Simucal

AutoIt Scripts:Aimbot: Proof of Concept - PixelSearching Aimbot with several search/autoshoot/lock-on techniques.Sliding Toolbar - Add a nice Sliding Toolbar to your next script. Click the link to see an animation of it in action!FontInfo UDF - Get list of system fonts, or search to see if a particular font is installed.Get Extended Property UDF - Retrieve a files extended properties (e.g., video/image dimensions, file version, bitrate of song/video, etc)
Link to comment
Share on other sites

Welcome netdawg,

The AutoIt Beta has Regular Expression support when you use Opt('WinTitleMatchMode', 4). If you use Opt('WinTitleMatchMode', 2), then you can do a substring within the title string. The Beta also has some better handling for CMD.exe with Standard I/O functions like STDOutRead() and more others to select from.

:think:

Link to comment
Share on other sites

I could not get StdoutRead out to work...

...but it was my first attempt at using the function.

Will StdoutRead work with a 16 bit app?

Any thoughts on a better Run line?

Edit: This code does work, but it does not hide the dos window.

Requires the Beta version of AutoIt:

AutoItSetOption("SendKeyDelay", 1);(milliseconds)
AutoItSetOption("WinWaitDelay", 1);(milliseconds)
AutoItSetOption("WinTitleMatchMode", 2);match substring
AutoItSetOption("TrayIconDebug", 1);0-off

Run(@AutoItExe & ' /AutoIt3ExecuteLine ' & _
        """Run('C:\smpdbk\SMPDBK.EXE', 'C:\smpdbk\')""")

If WinWaitActive("SMPDBK.EXE") Then
    Send("{ENTER}")
    Sleep(10)
    Send("NO{ENTER}")
    Sleep(10)
    Send("YES{ENTER}")
    Sleep(10)
    Send("INPUT.TXT{ENTER}")
    Sleep(50)
    Send("NO{ENTER}")
    Sleep(10)
    Send("OUTPUT.TXT{ENTER}")
    Sleep(10)
    Send("{ESC}")
Else
    MsgBox(0, "NOT ACTIVATED:", "SMPDBK.EXE")
EndIf
If you want to work on this... here is a partial quote from netdawg in the TechNet forum:

If you REALLY would like to accept "Mission Impossible", ... all files

needed are available by public FTP:

ftp://ftp.pdc.org/pub/smpdbk/

Run self-extracting file first smpdbk91.exe...the program is "smpdbk.exe"

and the input file (redirect) is run.txt. Obviously, this input file is

missing the ESC character, since I don't know how to feed ESC in this

fashion. The INPUT.TXT file is actually called WAI.TXT in this FTP.

Edited by herewasplato

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

Ahh.. I see now. Some dos applications dont use the std IO functions, but instead write directly to the console (like Microsofts telnet).

I have actually heard of a work around for this by using DLL calls to directly read the console buffer itself in a loop. There are some inherint problems with this, like if data is being sent to the buffer at a fast rate, you will miss some of it, etc. However, I think for a script like this it would work fine.

I know of one scripting language that is based on reading information sent directly to console and interacting with those applications. It is called "Expect". I have never used it, I have just read about it when trying to find a solution to this problem myself awhile back.

Here is a link: http://expect.nist.gov/

Or, you could just keep using your Sleep, Sends, etc... I dont think it will be that big of a deal for this sort of project.

-Simucal

AutoIt Scripts:Aimbot: Proof of Concept - PixelSearching Aimbot with several search/autoshoot/lock-on techniques.Sliding Toolbar - Add a nice Sliding Toolbar to your next script. Click the link to see an animation of it in action!FontInfo UDF - Get list of system fonts, or search to see if a particular font is installed.Get Extended Property UDF - Retrieve a files extended properties (e.g., video/image dimensions, file version, bitrate of song/video, etc)
Link to comment
Share on other sites

This is a bit of a thread hijack, since the OP never asked for help...

Could some one comment on why this works:

(Edit: the DOS window stay thru the rest of the script)

Run(@AutoItExe & ' /AutoIt3ExecuteLine ' & _
        """Run('C:\smpdbk\SMPDBK.EXE', 'C:\smpdbk\')""")

If WinWaitActive("SMPDBK.EXE") Then.....

While this does not:

(Edit: the DOS window just flashes by)

Run('C:\smpdbk\SMPDBK.EXE', 'C:\smpdbk\')
;window with expected title, but the program never loads
If WinWaitActive("SMPDBK.EXE") Then.....

I started with this:

Run(@ComSpec & ' /c C:\smpdbk\SMPDBK.EXE', 'C:\smpdbk\')
;works, but makes the WinWaitActive line OS sensitive
If WinWaitActive("cmd.exe") Then.....
but as I understand it, that would not work on W98 and the like.

(Edit: because it will produce a window named "...cmd.exe" on some - but not all - OSs.)

I'll get back to StdoutRead if I ever figure it out.

Edited by herewasplato

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

Like I said in my post, Stdout Read and Write wont work. This program writes directly to console, not using conventional IO Std's. This is the same reason it is a bitch to script Microsoft Telnet.

AutoIt Scripts:Aimbot: Proof of Concept - PixelSearching Aimbot with several search/autoshoot/lock-on techniques.Sliding Toolbar - Add a nice Sliding Toolbar to your next script. Click the link to see an animation of it in action!FontInfo UDF - Get list of system fonts, or search to see if a particular font is installed.Get Extended Property UDF - Retrieve a files extended properties (e.g., video/image dimensions, file version, bitrate of song/video, etc)
Link to comment
Share on other sites

Like I said in my post, Stdout Read and Write wont work. This program writes directly to console, not using conventional IO Std's. This is the same reason it is a bitch to script Microsoft Telnet.

This code almost works:
;http://www.autoitscript.com/forum/index.php?s=&showtopic=24733
;http://www.autoitscript.com/forum/index.php?s=&showtopic=1205&view=findpost&p=7337  ntvdm

AutoItSetOption("SendKeyDelay", 1) ;(milliseconds)
AutoItSetOption("WinWaitDelay", 1) ;(milliseconds)
AutoItSetOption("WinTitleMatchMode", 2);match substring
AutoItSetOption("TrayIconDebug", 1) ;0-off

Do
    ProcessClose("ntvdm.exe")
    Sleep(10)
Until Not ProcessExists("ntvdm.exe")

Dim $CMDoutput, $ProcessID

$ProcessID = Run(@ComSpec & ' /c C:\smpdbk\SMPDBK.EXE', 'C:\smpdbk\', @SW_SHOW, 7)

While 1
    $CMDoutput &= StdoutRead($ProcessID)
    If StringInStr($CMDoutput, "HIT ENTER TO CONTINUE") Then
        StdinWrite($ProcessID, "{ENTER}")
        $CMDoutput = ""
        ExitLoop
    EndIf
    Sleep(10)
WEnd

While 1
    $CMDoutput &= StdoutRead($ProcessID)
    If StringInStr($CMDoutput, "IS THIS A NATIONAL WEATHER SERVICE OFFICE (E.G., RH, RFC, WSFO)?") Then
        StdinWrite($ProcessID, "NO{ENTER}")
        $CMDoutput = ""
        ExitLoop
    EndIf
    Sleep(10)
WEnd

While 1
    $CMDoutput &= StdoutRead($ProcessID)
    If StringInStr($CMDoutput, "DO YOU WISH TO RUN AN EXISTING FILE?  (ENTER YES OR NO)") Then
        StdinWrite($ProcessID, "YES{ENTER}")
        $CMDoutput = ""
        ExitLoop
    EndIf
    Sleep(10)
WEnd

While 1
    $CMDoutput &= StdoutRead($ProcessID)
    If StringInStr($CMDoutput, "WHAT IS NAME OF THE DATA SET YOU WISH TO RUN?") Then
        StdinWrite($ProcessID, "INPUT.TXT{ENTER}")
        $CMDoutput = ""
        ExitLoop
    EndIf
    Sleep(10)
WEnd

While 1
    $CMDoutput &= StdoutRead($ProcessID)
    If StringInStr($CMDoutput, "DO YOU WANT YOUR OUTPUT TO COME TO THE TERMINAL?") Then
        StdinWrite($ProcessID, "NO{ENTER}")
        $CMDoutput = ""
        ExitLoop
    EndIf
    Sleep(10)
WEnd

While 1
    $CMDoutput &= StdoutRead($ProcessID)
    If StringInStr($CMDoutput, "ENTER THE FILENAME FOR THE OUTPUT INFORMATION:") Then
        StdinWrite($ProcessID, "OUTPUT.TXT{ENTER}")
        $CMDoutput = ""
        ExitLoop
    EndIf
    Sleep(10)
WEnd

ProcessWait("ntvdm.exe")

Do
    ProcessClose("ntvdm.exe")
    Sleep(10)
Until Not ProcessExists("ntvdm.exe")

If Not StringInStr(FileRead('C:\smpdbk\OUTPUT.TXT'), "ANALYSIS IS COMPLETE") Then
    MsgBox(0, "", "Error")
Else
    MsgBox(0, "", "ANALYSIS IS COMPLETE")
EndIf

FileDelete("C:\Temp\scs???.tmp")
OUTPUT.TXT is incomplete and terminating ntvdm like that leaves tmp files behind... see the link at the top of the code.

Don't laugh at my loops, I could not get it to set @error.

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

This code almost works:

=(Code)=

OUTPUT.TXT is incomplete and terminating ntvdm like that leaves tmp files behind... see the link at the top of the code.

Don't laugh at my loops, I could not get it to set @error.

Sadly I don't have it in me to make a monkey-puzzle of this one. I'm not surprised that @error doesn't get set; when I tried running the app on XPSP2 I got a message because the app had terminated abruptly, so it probably doesn't do any cleanup of its output connection as far as XP is concerned, either (or that was the cause of the message).

The app itself is a self-proclaimed 8-bit app that would run on the oldest IBM-compatible PC, and has full-screen DOS *GA graphics, so there's no telling what layers of emulation are being laid down by Windows to get it do do what it does. Taking that into account I'm not surprised at the observed poor behavior of StdoutRead, which is really intended for apps that interact through simple print-to-console operations...

Sorry, I'm not going to tilt at this windmill. :think:

Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.

Link to comment
Share on other sites

...Sorry, I'm not going to tilt at this windmill. :think:

Thanks for your reply/post to my PM on this topic.

I'll let the STD I/O thing go for now - just my luck that I picked a weird one learn on.

(and thanks Simucal for your help on this)

One last thing:

I've read what I could find on /AutoIt3ExecuteLine and I still don't understand the question posed in this post: http://www.autoitscript.com/forum/index.ph...ndpost&p=173588

It would seem to me that the first two blocks of code should yield the exact same results. For this script, I'm glad that they don't, but puzzled as to why.

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

I don't see any obvious reason why directly calling the EXE doesn't work.

For any non-Win32 app it's best to call it with @ComSpec /c so that the shell can work its magic. If you're concerned about compatibility between the Windows versions you can use the string value of @ComSpec itself to determine what window title to test for...

Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.

Link to comment
Share on other sites

Wow! Dear herewasplato and others: Amazing work...

The key (no pun intended) to this is that ESC key (the very last response to the SMPDBK) has to be "force-fed" into the ntvdm process that owns SMPDBK exactly as if it came in from the keyboard. Nothing except AutoIt Script is able to do that, not even Microsoft's own shell.

Otherwise, as you guys noted, the output is incomplete (and scientifically useless). Killing ntdvm, therefore, proved pointless. Got unstable results by spawning dual parallel threads PROGRAMMATICALLY, one running my SMPDBK1.AU3 (the DOS based SMPDBK "GUI") and the other SMPDBK2.AU3 (which simulates user responses to the prompts from process 1) either from Java, MSH or even AutoIt script like SMPDBK0 (as noted).

The ONLY thing that works 100% is manually running the SPMDBK1.EXE and SPMDBK2.EXE (executable versions of the corresponding *.AU3) by double clicking from XPSP2 explorer in exact 1-2 sequence.

Seems good enough for now, but I would like this to be one step that can be integrated into the pre-processing that generates INPUT.TXT and the post-processing that takes OUTPUT.TXT and ingests into a vizualization program. Thats four steps that can be one single smooth step (.EXE) if SMPDBK could be automated in a single step.

Or am I missing the fact that you guys have a solution?!

Please enlighten me if that is the case...and thanks VERY much for your efforts, in any case.

Link to comment
Share on other sites

Wow! Dear herewasplato and others: Amazing work...

<snipped>

Or am I missing the fact that you guys have a solution?!

Please enlighten me if that is the case...and thanks VERY much for your efforts, in any case.

Thanks.

When I run your two scripts, I still see the last screen flash by ever so briefly.

The code posted here:

http://www.autoitscript.com/forum/index.ph...ndpost&p=173540

works as an all in one exe, but you will see the DOS window for a brief time followed by the "last screen" for a short time. That code requires the beta version of AutoIt3.

Here is the version that I compiled and used for testing:

AutoItSetOption("SendKeyDelay", 1) ;(milliseconds)
AutoItSetOption("WinWaitDelay", 1) ;(milliseconds)
AutoItSetOption("WinTitleMatchMode", 2);match substring
AutoItSetOption("TrayIconDebug", 1) ;0-off

For $i = 1 To 30
    If FileExists('C:\smpdbk\OUTPUT.TXT') Then
        Do
            Sleep(30)
        Until FileDelete('C:\smpdbk\OUTPUT.TXT')
    EndIf
    
    Run(@AutoItExe & ' /AutoIt3ExecuteLine ' & _
            """Run('C:\smpdbk\SMPDBK.EXE', 'C:\smpdbk\')""")
    
    If WinWaitActive("SMPDBK.EXE") Then
        Send("{ENTER}")
        Sleep(10)
        Send("NO{ENTER}")
        Sleep(10)
        Send("YES{ENTER}")
        Sleep(10)
        Send("INPUT.TXT{ENTER}")
        Sleep(50)
        Send("NO{ENTER}")
        Sleep(10)
        Send("OUTPUT.TXT{ENTER}")
        Sleep(10)
        Send("{ESC}")
    Else
        MsgBox(0, "NOT ACTIVATED:", "SMPDBK.EXE")
    EndIf
    
    Sleep(1000)
    
    If Not StringInStr(FileRead('C:\smpdbk\OUTPUT.TXT'), "ANALYSIS IS COMPLETE") Then
        MsgBox(0, "", "Error")
    Else
        MsgBox(0, "", "ANALYSIS IS COMPLETE", 3)
    EndIf
    
Next
out of about 90 runs, I had no failures... but sleeps are so dependant on the computer running the code. I would consider making them 10 times longer.

So yes, you can have it all in one exe if you are willing to give up @SW_HIDE. I could not make that work any other way than as you mentioned...

...enjoy...

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...