Jump to content

Recommended Posts

Posted (edited)

Hi everyone,

I have a question :) What I'm trying to do is make a script that writes a .bat file and then it has to execute that .bat file. The problem is that when I write the .bat file in my script and "close" the file AutoIt still has it open somehow. Because when I have closed the file it still doesn't work, but when I run the .bat manually it works fine, so apparently AutoIt somehow prevents the file from being executed.

I understand this all sound kinda vague, so here's some example code:

; make a .bat file
$file = FileOpen("ftp test 2.bat", 2)

If $file = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

; example code for .bat file
FileWrite($file, "ping 1.1.1.1")
; close the .bat file
FileClose($file)
; now run it, 
; this is the part that doesn't work
Run("ftp test 2.bat")

So does anyone know a way to do this? (and I don't mean pinging :)) If anyone knows another thread where this was asked before that's also fine, but I simply could find anything like this (but I also don't know how I would phrase this problem best for searching...) Any help is greatly appreciated :P

Edit: If anyone can tell me a way to communicate with the cmd window that's fine too for what I want to use it. But it has to be able to see the responses of the cmd window as well. For example to see when the ping finishes so it can send the next command, "exit" for example. Again any help is greatly appreciated :idea:

Edited by CyberneticSoldier
Posted

The problem was it was trying to run the program ftp. If you want to do it like that then you could do

$file = FileOpen("ftp test 2.bat", 2)
If $file = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf
FileWrite($file, "ping 1.1.1.1")
FileClose($file)
Run(@ScriptDir & "\ftp test 2.bat")

Also if your only writing one line or even just a couple you really don't have to do file open. Plus if you want to work with dos you can try using _RunDOS.

Posted (edited)

Thanks Onichan :) Also I didn't see the _RunDOS command before... I'll take a look to see if it can do what I want it to :)

Just a question, can the _RunDOS command do multiple lines of code? I assume it can if I separate them somehow? Also if I run multiple _RunDOS commands after each other will it run those in one window, or will it open a new window for every separate _RunDOS?

Edited by CyberneticSoldier
Posted (edited)

I have only used _RunDOS a little and never tried multiple lines of code but I would guess you would have to do a new _RunDOS for each line of code also if you do run multiple _RunDOS it will run them each in their own window and it will automatically wait for the process to finish before continuing for example

#include <Process.au3>
Local $a, $b
$a = _RunDOS("ping 1.1.1.1")
MsgBox(0,'',"Exit code for 1.1.1.1:" & $a & " Error code:" & @error)
$b = _RunDOS("ping 127.0.0.1")
MsgBox(0,'',"Exit code for 127.0.0.1:" & $b & " Error code:" & @error)

but thats if you just want for some commands to run and exit. If you want to interact with the command window then thats different. Im not sure if you can interact much with cmd after you run it but I made a couple scripts a while back that does get data from cmd window heres the main part of one that checked for time sync errors

$Run = Run(@ComSpec & ' /c w32tm /monitor', @SystemDir, @SW_HIDE, 6) ; starts w32tm.exe in a hidden command windows with the /monitor variable
While ProcessExists($Run) ; takes a while for it to finish so keep reading its output
    Sleep(100)
    $Time = StdoutRead($Run, True) ; this just saves the most recent output to the $time variable now depending on how the program works you may want to use $time &= StdoutRead($Run, True)
 ; to add all the output data but w32tm.exe just puts garbage in front of the actual data
WEnd
$aTime = StringSplit($Time, @LF) ; its one big string of data so need to split it to multiple lines so each server is on its own
For $x = 1 To UBound($aTime) - 1    ; then the rest of it just goes through looking for servers off time and then saves that to a string
    If StringRegExp($aTime[$x], "(NTP: )[+-][1-9]{1,9}\d{0,9}") Then
        $r = StringRegExp($aTime[$x], "(?i:NTP: )[+-][1-9]{1,9}\d{0,9}", 1)
        $s = StringRegExp($aTime[$x - 2], "\w{6,9}", 1)
        If StringRegExp($aTime[$x - 2], "(?i)(o)0[1-9](c)|(?i)(oo)0[1-9](c)") Then
            $Time = "Red"
        EndIf
        $Time2 &= $s[0] & " " & $r[0] & @LF
    EndIf
Next

you should be able to use that for getting data after you run a command. Now if its an external program I do know you can send input to it while its hidden which here is part of one I used to backup our network devices. It used plink which is the command line version of putty which is a terminal program

Local $a = False
$IP = @IPAddress1
; this was designed to be multithreaded so thats why i use $cmdline
If Ping($CmdLine[1], 2000) Then
    $PID1 = Run(@TempDir & "\plink.exe -ssh -l " & $CmdLine[3] & " -pw " & $CmdLine[4] & " " & $CmdLine[1] & " copy run tftp:", "", @SW_HIDE, 7) ;runs plink and enters text "copy run tftp:"
    For $n = 1 To 45 ; some devices took forever to respond because of high latency so had to wait up to 45 seconds
        Sleep(1000)
        $OUT1 = StdoutRead($PID1) ; keep checking for output from plink
        If StringInStr($OUT1, "Address or name of remote host []?") Then ; looks at output to look for response
            StdinWrite($PID1, $IP & @CRLF & @CRLF) ; writes the ip into the hidden window and presses enter twice
            $a = True
            Sleep(5000) ; waits for it to copy
            ExitLoop
        EndIf
    Next
    ProcessClose($PID1)
    If $a = False Then ; if that didnt work try something else
    ; more code was here to try again with different settings but you get the idea

I haven't used those in a while so no guarantee that they work.

Edited by Onichan
Posted

Alright, so StdoutRead can read output from a process, that sounds interesting and might be enough for what I want to do. Thanks for all your help Onichan :)

If I have other questions I'll let you know, but I think I've got everything I need now :)

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
  • Recently Browsing   0 members

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