- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
udtStart.cb = Len(udtStart)
udtStart.dwFlags = STARTF_USESHOWWINDOW
udtStart.wShowWindow = SW_HIDE
RtlZeroMemory udtSecurity, Len(udtSecurity)
udtSecurity.nLength = Len(udtSecurity)
lRet = CreateProcess(vbNullString, sEXEPath & sProgName & _
".EXE >" & sTempPath & sErrFile, _
udtSecurity, udtSecurity, 1, NORMAL_PRIORITY_CLASS, 0, vbNullString, _
udtStart, udtProcInfo)
' Wait for the shelled application to finish:
lRet = WaitForSingleObject(udtProcInfo.hProcess, 6000)
'lShell = Shell(sEXEPath & sProgName & ".EXE", vbHide)
'lHndl = OpenProcess(PROCESS_QUERY_INFORMATION, 0, lShell)
''lRet = WaitForSingleObject(lHndl, INFINITE)
'lRet = WaitForSingleObject(lHndl, 6000)
If lRet = WAIT_TIMEOUT Then
lRet = CloseHandle(lHndl)
lHndl = OpenProcess(PROCESS_TERMINATE, 0, lShell)
If lHndl = 0 Then Exit Sub
lRet = TerminateProcess(lHndl, 0)
ElseIf lRet = WAIT_FAILED Then
MsgBox "Error Calling Program EXE - #" & Err.LastDllError & _
". Please contact CAE.", iMsgBox
GoTo RunProgErr
End If
lRet = CloseHandle(lHndl)
lRet = CloseHandle(lFileHndl)
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Jugoslav,
I've modified my CreateProcess call according to your response, but still no luck on getting the screen output to appear in an error file. The code now looks like:
' open a file to catch errors
udtSecurity.nLength = Len(udtSecurity)
lFileHndl = CreateFile(sTempPath & sErrFile, FILE_WRITE_DATA, 0, _
udtSecurity, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, ByVal 0&)
' Initialize the STARTUPINFO structure:
udtStart.cb = Len(udtStart)
udtStart.dwFlags = STARTF_USESHOWWINDOW
udtStart.wShowWindow = SW_NORMAL
udtStart.hStdOutput = lFileHndl
udtStart.hStdError = lFileHndl
' Clear and re-Initialize the security attributes
RtlZeroMemory udtSecurity, Len(udtSecurity)
udtSecurity.nLength = Len(udtSecurity)
' Start the shelled application:
lRet = CreateProcess(vbNullString, sEXEPath & sProgName & ".EXE", _
udtSecurity, udtSecurity, True, NORMAL_PRIORITY_CLASS, 0, vbNullString, _
udtStart, udtProcInfo)
' Wait for the shelled application to finish:
lRet = WaitForSingleObject(udtProcInfo.hProcess, 6000)
If lRet = WAIT_TIMEOUT Then
lRet = CloseHandle(lHndl)
lHndl = OpenProcess(PROCESS_TERMINATE, 0, lShell)
If lHndl = 0 Then Exit Sub
lRet = TerminateProcess(lHndl, 0)
ElseIf lRet = WAIT_FAILED Then
MsgBox "Error Calling Program EXE - #" & Err.LastDllError & _
". Please contact CAE.", iMsgBox
GoTo RunProgErr
Else
'check normal/abnormal termination
lRet = GetExitCodeProcess(udtProcInfo.hProcess, lExit)
If lExit <> 0 Then _
MsgBox "An error occurred while attempting to run " & sProgName & _
" . Please examine your input data for errors.", iMsgBox
End If
lRet = CloseHandle(lHndl)
lRet = CloseHandle(lFileHndl)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Jugoslav,
I was justlogging on to tell you that I found STARTF_USESTDHANDLES and got the code to work when I saw your post. Yay!!! Thanks for sending me in the right direction.
Robin
For anyone else who may be tackling a similar issue, this is what my final result looks like:
' open a file to catch errors
udtSecurity.nLength = Len(udtSecurity)
udtSecurity.bInheritHandle = True
lFileHndl = CreateFile(sTempPath & sErrFile, FILE_WRITE_DATA, 0, _
udtSecurity, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, ByVal 0&)
' Initialize the STARTUPINFO structure:
udtStart.cb = Len(udtStart)
udtStart.dwFlags = STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES
udtStart.wShowWindow = SW_HIDE
udtStart.hStdOutput = lFileHndl
udtStart.hStdError = lFileHndl
' Clear and re-Initialize the security attributes
RtlZeroMemory udtSecurity, Len(udtSecurity)
udtSecurity.nLength = Len(udtSecurity)
' Start the shelled application:
lRet = CreateProcess(vbNullString, sEXEPath & sProgName & ".EXE", _
udtSecurity, udtSecurity, True, NORMAL_PRIORITY_CLASS, 0, vbNullString, _
udtStart, udtProcInfo)
' Wait for the shelled application to finish:
lRet = WaitForSingleObject(udtProcInfo.hProcess, 6000)
If lRet = WAIT_TIMEOUT Then
lRet = CloseHandle(lHndl)
lHndl = OpenProcess(PROCESS_TERMINATE, 0, lShell)
If lHndl = 0 Then Exit Sub
lRet = TerminateProcess(lHndl, 0)
ElseIf lRet = WAIT_FAILED Then
MsgBox "Error Calling Program EXE - #" & Err.LastDllError & _
". Please contact CAE.", iMsgBox
GoTo RunProgErr
Else
'check normal/abnormal termination
lRet = GetExitCodeProcess(udtProcInfo.hProcess, lExit)
If lExit <> 0 Then _
MsgBox "An error occurred while attempting to run " & sProgName & _
" . Please examine your input data for errors.", iMsgBox
End If
lRet = CloseHandle(lHndl)
lRet = CloseHandle(lFileHndl)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
Thanks for the reply. We haven't really played with the Fortran Windows applications because we're pretty well versed in VB and it is so easy to use. (We haven't moved to .NET yet - that may change our opinion!) We love CVF for the DLL and console application creation, because we have a LARGE library of legacy code in Fortran on anancient mainframe.
In this case, we're creating console applications to rapidly port the mainframe programs to the PC. Since the mainframe versions of these programs read from JCL and write to the output queue, its easy to convert them to console apps that read a text file and write a text file.
Thanks for the suggestion - we'll have to check out those Windows apps!
Robin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CloseHandle(udtProcInfo.hProcess)
CloseHandle(udtProcInfo.hThread)
Just a comment on design :
Right now you detect the presence of errors but not the specific error(s). That's not very useful to the user. Why don't you use VB to validate the input so that whatever error(s) the app generates won't be of the user's doing? When you've bullet proofed the input you won't need to generate a user error file and then you can focus on figuring out how to handle those errors that are of the apps sole creation.
Ciao,
Gerry T.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Gerry,
That's a great idea if its possible to use VB to validate the user's input. In this case, the programs we are working with do engineering analysis and the input data can be valid within a certain range, but the combination of input data may cause a divide by zero or square root of -1. In most cases, it's not blatantly obvious which combination of input data will cause a crash, or where the crash will occur. Ideally, there would be an error trap at every SQRT or / operation in the Fortran. That's not always practical with our large programs.Sinceour goal is to rapidly migrate a lot of programs, it's enough at this point to detect the fatal exception and alert the user without crashing the user interface.
We do perform input validation to make sure the user's input is inside of the valid ranges.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Despite this, the unforeseen happens and the Fortran app has to respond. The CVF docs has an excellent discussion on the use of Windows(C/C++) SEH to overcome Fortran's lack of support for exception handling, including those of the floating point variety. For math lib exceptions you have to supply a MATHERRQQ subroutine. However, if your Fortran is a DLL then to use MATHERRQQ you must link against the _static_ C rtl.
Ciao,
Gerry T.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Gerry,
I wasn't aware that I could handle the Fortran run-time errors inside of the Fortran code. How exciting! I'll have to look at the SEH and start using it in our code. Thanks for the tip!
Have a great weekend!
Robin

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page