INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

API Functions

How can I get the DOS Errorlevel from executed program? by wgcs
Posted: 20 Nov 02 (Edited 20 Nov 02)

This seems easy to do, but it requires you to get the process handle of the launched program (which could be an .EXE, or a .BAT, as in the example below).

In VFP:
lcBatchFile = FULLPATH('MyBatFile.BAT')
lnExitCode = RunExitCode( getenv('COMSPEC'), "/c "+lcBatchFile )


In File MyBatFile.BAT:
@echo off
cls
call 3rdparty.exe

if errorlevel 10 goto error10
if errorlevel 5 goto error5
if errorlevel 0 goto error0

gotoend

:error10
echo Error 10 - Invalid command line syntax.
EXIT 10
gotoend

:error5
echo Error 5 - Unable to read image file.
EXIT 5
gotoend

:error0
echo Error0 - all ok
EXIT 0

:end
EXIT 0


In file RunExitCode.prg:

**********************************************************
* Program: RunExitCode.PRG                               *
* Author : William GC Steinford                          *
* Date   : Nov 2002                                      *
**********************************************************
FUNCTION RunExitCode
LPARAMETERS pcProgFile, pcCmdLine
* ?RunExitCode("c:\winnt\system32\cmd.exe", " /c dir c:\*.* > \temp\dir.txt")
DECLARE INTEGER CreateProcess IN kernel32;
    STRING   lpApplicationName,;
    STRING   lpCommandLine,;
    INTEGER  lpProcessAttributes,;
    INTEGER  lpThreadAttributes,;
    INTEGER  bInheritHandles,;
    INTEGER  dwCreationFlags,;
    INTEGER  lpEnvironment,;
    STRING   lpCurrentDirectory,;
    STRING   lpStartupInfo,;
    STRING @ lpProcessInformation

DECLARE LONG WaitForSingleObject in win32api ;
  INTEGER hHandle, LONG dwMilliseconds

DECLARE INTEGER GetExitCodeProcess in win32api ;
  INTEGER hProcess, INTEGER @ nExitCode

#DEFINE SW_SHOW      5
#DEFINE STILL_ACTIVE 0x103

cStartInfo = GetStartupInfo()

cProcessInfo = repl( chr(0), 12 )

*!*    typedef struct _PROCESS_INFORMATION {
*!*        HANDLE hProcess;
*!*        HANDLE hThread;
*!*        DWORD dwProcessId;
*!*        DWORD dwThreadId;
*!*    } PROCESS_INFORMATION;


if 0=CreateProcess( pcProgFile, pcCmdLine, ;
                    0,0,0,0,0,0, cStartInfo, @cProcessInfo )
  ?"Could not create process"                    
  RETURN -1
endif

hProcess = Buf2dword( left( cProcessInfo, 4 ) )
?"Process handle = "+Tran(hProcess)
* // Give the process time to execute and finish
nExitCode = STILL_ACTIVE
do while nExitCode=STILL_ACTIVE
  WaitForSingleObject(hProcess, 5000) && 5 seconds
  if 0<>GetExitCodeProcess(hProcess, nExitCode)
    do case
      case nExitCode=STILL_ACTIVE
        ?"Process is still active"
      otherwise
        ?"Exit code = "+ tran( nExitCode )
    endcase
  else
    ?"GetExitCodeProcess() failed"
    nExitCode = -2
  endif
enddo

RETURN nExitCode

* * *
* dword is compatible with LONG
FUNCTION  num2dword (lnValue)
#DEFINE m0       256
#DEFINE m1     65536
#DEFINE m2  16777216
    LOCAL b0, b1, b2, b3
    b3 = Int(lnValue/m2)
    b2 = Int((lnValue - b3*m2)/m1)
    b1 = Int((lnValue - b3*m2 - b2*m1)/m0)
    b0 = Mod(lnValue, m0)
RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)
* * *
* dword is compatible with LONG
FUNCTION  num2word (lnValue)
RETURN Chr(MOD(m.lnValue,256)) + CHR(INT(m.lnValue/256))
* * *
FUNCTION  buf2word (lcBuffer)
RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ;
    Asc(SUBSTR(lcBuffer, 2,1)) * 256
* * *
FUNCTION  buf2dword (lcBuffer)  
RETURN;  
    Asc(SUBSTR(lcBuffer, 1,1)) + ;  
    Asc(SUBSTR(lcBuffer, 2,1)) * 256 +;  
    Asc(SUBSTR(lcBuffer, 3,1)) * 65536 +;  
    Asc(SUBSTR(lcBuffer, 4,1)) * 16777216  
ENDFUNC  

* Thanks to www.news2news.com for Startupinfo structure definition
PROCEDURE  getStartupInfo
* creates the STARTUP structure to specify main window
* properties if a new window is created for a new process

*| typedef struct _STARTUPINFO {  
*|     DWORD   cb;                4
*|     LPTSTR  lpReserved;        4
*|     LPTSTR  lpDesktop;         4
*|     LPTSTR  lpTitle;           4
*|     DWORD   dwX;               4
*|     DWORD   dwY;               4
*|     DWORD   dwXSize;           4
*|     DWORD   dwYSize;           4
*|     DWORD   dwXCountChars;     4
*|     DWORD   dwYCountChars;     4
*|     DWORD   dwFillAttribute;   4
*|     DWORD   dwFlags;           4
*|     WORD    wShowWindow;       2
*|     WORD    cbReserved2;       2
*|     LPBYTE  lpReserved2;       4
*|     HANDLE  hStdInput;         4
*|     HANDLE  hStdOutput;        4
*|     HANDLE  hStdError;         4
*| } STARTUPINFO, *LPSTARTUPINFO; total: 68 bytes

#DEFINE STARTF_USESHOWWINDOW   1
#DEFINE SW_SHOWMAXIMIZED       3

RETURN  num2dword(68) +;
    num2dword(0) + num2dword(0) + num2dword(0) +;
    num2dword(0) + num2dword(0) + num2dword(0) + num2dword(0) +;
    num2dword(0) + num2dword(0) + num2dword(0) +;
    num2dword(STARTF_USESHOWWINDOW) +;
    num2word(SW_SHOWMAXIMIZED) +;
    num2word(0) + num2dword(0) +;
    num2dword(0) + num2dword(0) + num2dword(0)

Back to Microsoft: Visual FoxPro FAQ Index
Back to Microsoft: Visual FoxPro Forum

My Archive

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close