seckel
asked on
How do I get VB app to stop when batch exe fails?
I dynamically generate a Batch exe and execute it. My VB application waits until the batch exe has completed before continuing.
The code below returns an errorlevel of 1, how do I code my VB application to end when the batch exe fails with a errorlevel > 0?
Option Explicit
Dim gRWBackupBatchFileName
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const PROCESS_QUERY_INFORMATION As Long = &H400
Private Const STILL_ACTIVE As Long = &H103
Private Sub Form_Load()
Call CreateRWBackupBatch
Call ExecuteRWBackupBatch
MsgBox ("Test failed!")
End
End Sub
Public Sub CreateRWBackupBatch()
On Error GoTo er_CreateRWBackupBatch
gRWBackupBatchFileName = App.Path & "\test.bat"
Open gRWBackupBatchFileName For Output Access Write Lock Read Write As 1
Print #1, "@echo off"
Print #1, ""
Print #1, "copy x.txt y.txt"
Print #1, ""
Print #1, "echo %errorlevel%"
Print #1, "exit"
Close #1
er_CreateRWBackupBatch:
If Err.Number <> 0 Then
MsgBox Str(Err.Number) & ": " & Err.Description, , "Create Batch Error"
End
End If
End Sub
Public Sub ExecuteRWBackupBatch()
On Error GoTo er_ExecuteRWBackupBatch
WaitForProcess Shell(gRWBackupBatchFileNa me, vbMinimizedNoFocus)
er_ExecuteRWBackupBatch:
If Err.Number <> 0 Then
MsgBox Str(Err.Number) & ": " & Err.Description, , "Execute Batch Error"
End
End If
End Sub
Public Function WaitForProcess(ProcessID As Long) As Long
Dim hProcess As Long
Dim RetVal As Long
RetVal = -1 'Default return value
hProcess = OpenProcess(STANDARD_RIGHT S_REQUIRED + PROCESS_QUERY_INFORMATION, 0, ProcessID) ' Try to open process
'Start polling to see if the process has terminated
If hProcess <> 0 Then
Do
GetExitCodeProcess hProcess, RetVal
Sleep (100)
DoEvents
Loop While RetVal = STILL_ACTIVE
End If
CloseHandle hProcess
WaitForProcess = RetVal
End Function
The code below returns an errorlevel of 1, how do I code my VB application to end when the batch exe fails with a errorlevel > 0?
Option Explicit
Dim gRWBackupBatchFileName
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const PROCESS_QUERY_INFORMATION As Long = &H400
Private Const STILL_ACTIVE As Long = &H103
Private Sub Form_Load()
Call CreateRWBackupBatch
Call ExecuteRWBackupBatch
MsgBox ("Test failed!")
End
End Sub
Public Sub CreateRWBackupBatch()
On Error GoTo er_CreateRWBackupBatch
gRWBackupBatchFileName = App.Path & "\test.bat"
Open gRWBackupBatchFileName For Output Access Write Lock Read Write As 1
Print #1, "@echo off"
Print #1, ""
Print #1, "copy x.txt y.txt"
Print #1, ""
Print #1, "echo %errorlevel%"
Print #1, "exit"
Close #1
er_CreateRWBackupBatch:
If Err.Number <> 0 Then
MsgBox Str(Err.Number) & ": " & Err.Description, , "Create Batch Error"
End
End If
End Sub
Public Sub ExecuteRWBackupBatch()
On Error GoTo er_ExecuteRWBackupBatch
WaitForProcess Shell(gRWBackupBatchFileNa
er_ExecuteRWBackupBatch:
If Err.Number <> 0 Then
MsgBox Str(Err.Number) & ": " & Err.Description, , "Execute Batch Error"
End
End If
End Sub
Public Function WaitForProcess(ProcessID As Long) As Long
Dim hProcess As Long
Dim RetVal As Long
RetVal = -1 'Default return value
hProcess = OpenProcess(STANDARD_RIGHT
'Start polling to see if the process has terminated
If hProcess <> 0 Then
Do
GetExitCodeProcess hProcess, RetVal
Sleep (100)
DoEvents
Loop While RetVal = STILL_ACTIVE
End If
CloseHandle hProcess
WaitForProcess = RetVal
End Function
ASKER
This copy code will generate an errorlevel of 1.
I need to know how to capture the errorlevel ( > 0) so I can trigger my VB application to stop instead of continue on.
I need to know how to capture the errorlevel ( > 0) so I can trigger my VB application to stop instead of continue on.
The errorlevel returned from the batch file will still be zero even if the copy command fails. You can only check the errorlevel of a statement in a batch file, from within the batch file.
Why are you creating a batch file to do a simple file copy?
Just use the built in copy function in VB and check for errors:
Private Sub Command1_Click()
On Error GoTo FileCopyError
FileCopy "x.txt", "y.txt"
Exit Sub
FileCopyError:
MsgBox Err.Description, vbCritical, "Error " & Err.Number
End Sub
~IM
Why are you creating a batch file to do a simple file copy?
Just use the built in copy function in VB and check for errors:
Private Sub Command1_Click()
On Error GoTo FileCopyError
FileCopy "x.txt", "y.txt"
Exit Sub
FileCopyError:
MsgBox Err.Description, vbCritical, "Error " & Err.Number
End Sub
~IM
ASKER
I didn't make it clear about the copy command...I am only using it to produce a desired errorlevel.
When I copy a file that exists, I force an errorlevel of 0 meaning the command was successful.
When I copy a file that does not exist, I am forcing the batch file to return an errorlevel of 1, which means not successful. With the echo command, I can see that my copy command returns an errorlevel of 1.
Now I need to know how I can get my VB application to recognize the errorlevel, so that with any batch I chose to execute from the VB application, I can know if it worked or not worked and take appropiate action within my VB application.
When I copy a file that exists, I force an errorlevel of 0 meaning the command was successful.
When I copy a file that does not exist, I am forcing the batch file to return an errorlevel of 1, which means not successful. With the echo command, I can see that my copy command returns an errorlevel of 1.
Now I need to know how I can get my VB application to recognize the errorlevel, so that with any batch I chose to execute from the VB application, I can know if it worked or not worked and take appropiate action within my VB application.
ASKER
"The errorlevel returned from the batch file will still be zero even if the copy command fails. You can only check the errorlevel of a statement in a batch file, from within the batch file."
Are you saying there is now system code that VB can check to verify if the bat completed successfully or not?
Java and C can do it, I would think VB can also...
Are you saying there is now system code that VB can check to verify if the bat completed successfully or not?
Java and C can do it, I would think VB can also...
The dos COPY command does not set ERRORLEVEL
If you want to get the results of a batch file operation the try redirecting the output into a txt file, and then check the file from VB
Print #1,"@echo off"
Print #1, ""
Print #1, "copy x.txt y.txt"
Print #1, ""
Print #1, "IF ERRORLEVEL 1 ECHO FAILED > RESULT.DAT"
Print #1, "exit"
Close #1
Then open the result.dat file from VB and check line failed
It is always better use alternate methods from VB or Windows API than depending on old DOS
If you want to get the results of a batch file operation the try redirecting the output into a txt file, and then check the file from VB
Print #1,"@echo off"
Print #1, ""
Print #1, "copy x.txt y.txt"
Print #1, ""
Print #1, "IF ERRORLEVEL 1 ECHO FAILED > RESULT.DAT"
Print #1, "exit"
Close #1
Then open the result.dat file from VB and check line failed
It is always better use alternate methods from VB or Windows API than depending on old DOS
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
AjithJoses method would certainly be simpler.
~IM
~IM
Is the purpose of this question to determine how to poll a batch file for execution status, or is the end goal to simply copy x.txt to y.txt?
You have a lot of advanced code to do a simple file copy! =)
There are functions built into VB to copy a file.
~IM