Question Running DOS commands and checking responces

wjburke2

Active member
Joined
Feb 3, 2009
Messages
29
Programming Experience
Beginner
I have a requirement to write a program that will watch a directory for a text file to be dropped into. It will always be active on a server. The text file will have one of two types of lines ?Exstream? or ?End-Program?. ?End-Program? will signal the program to shut down. ?Exstream? will indicate that in position 10-60 of that line is the name of a batch file that resides in another directory that needs to be executed.

I would like to read the batch file line by line looking for an Exstream command or a DOS copy statement then submit the command to DOS. I need to be able to determine if the command executed correctly and notify the user of success or failure. I would like to capture the DOS messages and send them to the user in an email. That way they would see the results and be able to respond accordingly. I have attached my program so far. In sub Process_Batch you will find some commented code that is supposed read the batch file and execute each line but I am not sure how to do this and capture the DOS messages. Anyone have any ideas?

VB.NET:
Imports System
Imports System.IO
Imports System.Timers
Imports System.Diagnostics
Imports System.Net.Mail

Module Module1

    Dim StartPath As String = "\\MyServer\122nd_PA_PGM\Exstream_Submit\"
    Dim ExstreamPath As String = "\\MyServer\ExstreamGMS\Bat\v8\"

    '**********************************
    ' Set the watch Directory here
    '**********************************
    Dim DIR_NAME As String = StartPath & "AutoBatchRun\"
    Dim di As New IO.DirectoryInfo(DIR_NAME)
    Dim FILE_NAME As String

    '**********************************
    ' Set the Archive Directory here 
    '**********************************
    Dim MoveDir As String = StartPath & "AutoBatchArchive\"
    Dim MoveName As String

    '**********************************
    ' Set the Log File Directory here 
    '**********************************
    Dim LogFile_Dir As String = StartPath & "Log_Files\"
    Dim Log_File As String

    '**********************************
    ' Set the Daily end time here
    '**********************************
    Dim EndTime As DateTime = #1:00:00 PM#

    Dim aTimer As System.Timers.Timer
    Dim StopSwitch As Boolean = False

    Dim strMsg As String
    Dim blnStatusGood As Boolean = True
    Dim strMessageBody As String

    Sub Main()

        Log_File = String.Format("{0}_ErrorLog.txt", DateTime.Today.ToString("yyyy_MM_dd"))

        Log_Events("Application Begin time")

        ' Create a timer with a 2 second interval.
        aTimer = New System.Timers.Timer(2000)

        ' Hook up the Elapsed event for the timer.
        AddHandler aTimer.Elapsed, AddressOf OnTimedEvent

        ' Set the Interval to 3 min for testing (60000 milliseconds = 1 min).
        aTimer.Interval = 180000
        aTimer.Enabled = True

        Application.Run()

    End Sub

    Private Sub OnTimedEvent(ByVal source As Object, ByVal e As ElapsedEventArgs)

        Dim aryFi As IO.FileInfo() = di.GetFiles("*.txt")
        Dim fi As IO.FileInfo
        Dim TextLine As String
        Dim FilesFound As Boolean = False
        Dim Batch_File As String

        'Debug.Print("The Elapsed event was raised at -> " & e.SignalTime)
        Log_Events("The Elapsed event was raised at -> " & e.SignalTime)

        For Each fi In aryFi

            Log_Events("Driver File Name: " & fi.Name)
            FILE_NAME = " "
            FILE_NAME = DIR_NAME & "\" & fi.Name

            '******************************
            '** Open/Read the Driver file
            '******************************
            Dim objReader As New System.IO.StreamReader(FILE_NAME)

            Try
                FilesFound = True
                Do While objReader.Peek() <> -1
                    TextLine = objReader.ReadLine()
                    If Mid(TextLine, 1, 11) = "END-PROGRAM" Then
                        StopSwitch = True
                    ElseIf (Mid(TextLine, 1, 8) = "EXSTREAM") Then
                        Batch_File = Mid(TextLine, 10, 50)
                        Process_Batch(Batch_File)
                    End If
                Loop

            Catch ex As Exception
                strMsg = "Error - OnTimedEvent " & ex.Message
                blnStatusGood = False
                SendStatusEmail(strMsg)
                Exit Sub

            End Try

            objReader.Dispose()

            If FilesFound = True Then
                MoveName = MoveDir & "\" & fi.Name
                If File.Exists(MoveName) Then
                    File.Delete(MoveName)
                End If
                File.Move(FILE_NAME, MoveName)
                Debug.Print(vbCrLf & "File Moved")
                strMessageBody = strMessageBody & "  Driver File Sudmitted " & "'" & FILE_NAME & "'" & vbCrLf
            End If
        Next

        If blnStatusGood = True And FilesFound = True _
        Or StopSwitch = True Then
            SendStatusEmail(" ")
        End If

        Dim Runtime As DateTime
        Runtime = TimeOfDay
        If TimeOfDay > EndTime _
        Or StopSwitch = True Then
            Debug.Print("Application Stoped" & Now)
            aTimer.Stop()
            Application.Exit()
            Exit Sub
        End If

    End Sub
    Private Sub Process_Batch(ByVal File_Name As Object)

        Dim TextLine As String
        Dim FilesFound As Boolean = False
        Dim Batch_File As String = ExstreamPath & File_Name & ".bat"

        If System.IO.File.Exists(Batch_File) <> True Then
            strMessageBody = strMessageBody & "  Batch File not found " & "'" & File_Name & "' " & Now & vbCrLf
            GoTo Exit_Process_Batch
        End If

        Dim objReader As New StreamReader(Batch_File)
        FilesFound = True

        '******************************
        '** Open/Read the Batch file
        '******************************
        Execute_Batch(Batch_File)

        'Try
        '    Do While objReader.Peek() <> -1
        '        TextLine = objReader.ReadLine()
        '        If (Mid(TextLine, 1, 5) = "Copy") _
        '        Or (Mid(TextLine, 1, 42) = "\\Exstream\Exstream_Engine_V8\ProdEngine") Then
        '            Execute_Batch(Batch_Command)
        '        End If
        '    Loop

        'Catch ex As Exception
        '    strMsg = "Error - OnTimedEvent " & ex.Message
        '    blnStatusGood = False
        '    SendStatusEmail(strMsg)
        '    Exit Sub

        'Finally
        '    objReader.Dispose()
        'End Try

Exit_Process_Batch:

    End Sub

    Sub Execute_Batch(ByVal Batch_file As String)
        On Error GoTo HandleErrors

        'Dim sYourCommand As String
        'ChDir(Dir1) 'since Dir1 is the current Directory
        'sYourCommand = "dir " & Dir1 & "> " & Dir1 & "\index.txt"
        'Shell("cmd /c " & sYourCommand, vbHide)

        Dim batchSuccessful As Integer
        Dim ExitCd As Integer

        Dim batchExecute As New Process()
        Dim batchExecuteInfo As New ProcessStartInfo()

        batchExecuteInfo.UseShellExecute = False

        ' Ued to hide the dos window "True = No Window"
        batchExecuteInfo.CreateNoWindow = True

        batchExecute.StartInfo = batchExecuteInfo
        batchExecute.StartInfo.FileName = Batch_file & " > " & MoveDir & "\vh.txt 2>&1"

        batchExecute.Start()
        batchExecute.WaitForExit(14400000) ' Set for 4 hour max run time

        ExitCd = batchExecute.ExitCode
        If ExitCd > 0 And Not batchExecute.HasExited Then
            blnStatusGood = False
            batchExecute.Kill()
        Else
            blnStatusGood = True
        End If

        batchExecute.Close()

Exit_Execute_Batch:
        Exit Sub

HandleErrors:

        strMsg = "Error - Execute_Batch " & Err.Number & ": " & Err.Description
        blnStatusGood = False
        SendStatusEmail(strMsg)
        GoTo Exit_Execute_Batch

    End Sub

    Private Sub Log_Events(ByVal EventMsg As String)

        Dim LogPath As String = LogFile_Dir & Log_File
        Dim fileExists As Boolean = File.Exists(LogPath)
        Dim writer As New IO.StreamWriter(LogPath, True)

        Try
            Using writer
                If Not fileExists Then
                    writer.WriteLine(DateTime.Now & " " & "Start Error Log for today")
                End If
                writer.WriteLine(DateTime.Now & " " & EventMsg)

            End Using
        Catch ex As IOException
            SendStatusEmail("Error writing to log file.")
        Finally
            If writer IsNot Nothing Then
                writer.Close()
            End If
        End Try

    End Sub
    Private Sub SendStatusEmail(ByVal strMsg As String)
        Dim emailClient As SmtpClient
        Dim ReportdDate As Date
        Dim strFrom As String
        Dim strSubject As String
        Dim strEmailRecipients As String

        ReportdDate = Now
        strFrom = "Exstream@MyCorp.com"
        strSubject = "Exstream Batch Process Run - " & ReportdDate
        strEmailRecipients = "ME@tmkmail.com, MYBOSS@tmkmail.com"

        Try
            Dim message As New MailMessage(strFrom, strEmailRecipients)

            If blnStatusGood Then
                message.Subject = strSubject
            Else
                message.Subject = strSubject & " - ** ERROR ** "
                strMessageBody = "Extream Batch Run Completed - " & Now() & vbCrLf & vbCrLf
                strMessageBody = strMessageBody & "Extream Batch Run - ** ERROR ** - See Details Below." & vbCrLf & vbCrLf
                strMessageBody = strMessageBody & "----- Status Log Details -------" & vbCrLf
                message.Body = strMessageBody & strMsg
                GoTo sendEmailExit
            End If

            If StopSwitch = True Then
                strMessageBody = strMessageBody & vbCrLf & "***** Extream Batch Process Stoped *****"
            End If

            strMessageBody = strMessageBody
            message.Body = "Extream Batch file Run Completed - " & Now() & vbCrLf & vbCrLf & strMessageBody

SendEmailExit:

            emailClient = New SmtpClient("mail.torchmarkcorp.com")
            emailClient.Send(message)

        Catch ex As Exception
            Console.WriteLine("Error sending status email: " & ex.Message)

        End Try

    End Sub

End Module
 
Last edited:
Ok, Some progress, This code successfuly executes a batch file sending the output and Error messages to a strings.
VB.NET:
Sub Execute_Batch_file(ByVal Batch_file As String)
        On Error GoTo HandleErrors

        Dim batchSuccessful As Integer
        Dim ExitCd As Integer

        Dim BatExec As New Process()
        Dim batExecInfo As New ProcessStartInfo(Batch_file)
        With batExecInfo
            .UseShellExecute = False
            .CreateNoWindow = True  ' Ued to hide the dos window "True = No Window"
            .RedirectStandardOutput = True
            .RedirectStandardError = True
        End With
        BatExec.StartInfo = batExecInfo

        batExec.Start()
        batExec.WaitForExit(14400000) ' Set for 4 hour max run time

        'Console.WriteLine(BatExec.StandardOutput.ReadToEnd())
        'Console.WriteLine(BatExec.StandardError.ReadToEnd())

        Dim srOutPut As StreamReader = BatExec.StandardOutput
        Dim strOutput As String = srOutPut.ReadToEnd
        strMessageBody = strMessageBody & "  System Messages " & vbCrLf & strOutput & vbCrLf

        Dim srError As StreamReader = BatExec.StandardError
        Dim strError As String = srError.ReadToEnd
        strMessageBody = strMessageBody & "  Error Messages " & vbCrLf & strError & vbCrLf

        ExitCd = batExec.ExitCode
        If ExitCd > 0 And Not batExec.HasExited Then
            blnStatusGood = False
            batExec.Kill()
        Else
            blnStatusGood = True
        End If

        batExec.Close()

Exit_Execute_Batch_File:
        Exit Sub

HandleErrors:

        strMsg = "Error - Execute_Batch " & Err.Number & ": " & Err.Description
        blnStatusGood = False
        SendStatusEmail(strMsg)
        GoTo Exit_Execute_Batch_File

    End Sub
 
Back
Top