Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Find and launch an external program
Message
 
 
À
07/09/2000 10:56:28
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Divers
Thread ID:
00413523
Message ID:
00413594
Vues:
13
>Is there an API call or a function to search a local drive for an executable, and then launch the program from Foxpro.
********************************************************************
*  Description.......: FindFileInNetwork
*  Calling Samples...: FindFileInNetwork("pdfmon.dll","c:\")
*  Parameter List....: pcFileToSearch,pcSearchPath, plEntireNetwork
*  Created by........: Houston Brennan 06/13/2000
*  Modified by.......: Nadya Nosonovsky 06/16/2000 11:30:52 AM (with assistance of BP and JH)
********************************************************************
lparameters pcFileToSearch,pcSearchPath, plEntireNetwork
** Check passed parameters

if vartype(pcFileToSearch)<>'C' or empty(pcFileToSearch)
     return .f.
endif

#define NoAttributesSet       0
#define readonly              1
#define hidden                2
#define system                4
#define Archived              32

#define DoNotSearchSubFolder  0
#define SearchSubFolder       1
local i, lcRetPath, lcDrive, lcSearchPath, StartTime,;
         prevonesc, prevescape, msgtail
lcRetPath=''

* note clock reading for generating final timing statistics
StartTime = seconds()                         && # seconds since midnight

* support user Escapes for interrupting the loop
prevonesc = on('escape')                    && save previous Escape handler
prevescape = set('escape')                    && previous Escape enablement state
set escape on                                   && enable escape handling
halt = .f.                                        && allow loop to run until this flag is toggled
on escape halt = .t.                         && force immediate termination if user escapes

* assemble fixed portion of status bar message outside of loop, for speed
msgtail = "...         Wait or press Esc to cancel ..."

wait window nowait 'Searching file '+pcFileToSearch+iif(plEntireNetwork,' in the whole network...',' ...')
oFiler = createobject( "Filer.FileUtil" )
oFiler.FileExpression = pcFileToSearch
oFiler.SubFolder = SearchSubFolder && Search all tree

if vartype(pcSearchPath)<>'C' or (empty(pcSearchPath) and !plEntireNetwork)
     lcSearchPath='c:\' && Local drive
else
    lcSearchPath=pcSearchPath     
endif     

if !plEntireNetwork && Only specified path to search
     oFiler = createobject( "Filer.FileUtil" )
     oFiler.SearchPath = lcSearchPath
     set message to 'Searching in '+lcSearchPath+msgtail
     oFiler.find(0) && Perform search
     if oFiler.files.count>0 && At least one file was found, pick up the first
          lcRetPath=oFiler.files.item[1].path
     endif
else
** Want to search in whole network
     for i = 67 to 90
          lcDrive = chr(i)
          if inlist(drivetype(lcDrive),3,4)
* Make sure the drive is ready (type 4 is either removeable or a network drive)
               set message to 'Searching drive '+lcDrive+msgtail
               oFiler.SearchPath = lcDrive+':\'
               oFiler.find(0) && Perform search
            if m.halt or lastkey()=27 && Escape was pressed
               exit
            endif    
               if oFiler.files.count>0 && At least one file was found, pick up the first
                    lcRetPath=oFiler.files.item[1].path
                    exit
               endif
          endif
     endfor
endif
* Restore settings
set escape &prevescape
on escape &prevonesc
set message to
wait clear
return lcRetPath && Path to the first found file

*!*     FOR iFile = 1 TO oFiler.Files.Count
*!*        ? iFile
*!*        ?? " "
*!*        ?? oFiler.Files.Item[ iFile ].Name
*!*        ?? " "
*!*        ?? oFiler.Files.Item[ iFile ].Attr
*!*        ?? " "
*!*        ?? oFiler.Files.Item[ iFile ].Path
*!*     NEXT iFile
*!*     RETURN .T.
NOTE AFAIK, Filer is not a distributable component, so you can use this program only on machines with VFP installed. For running external program I use Ed Rauh program (which I just renamed, I believe)
********************************************************************
*  Description.......: LaunchAppAndWait
*  Calling Samples...: 
*                      lcDir=justpath(oJC.OutTable)
*                       if file('C:\MAILERS\MP4W32.exe')
*                            pStatus=LaunchAppAndWait('C:\MAILERS\MP4W32.exe',lcDir)
*                       else
*                          =messagebox('Can not find Mailers program!',48,'Error')
*                          pStatus=0
*                       endif   
*  Parameter List....: tcCommandLine, tuFromDir, tcWindowMode
*  Created by........: Ed Rauh  
*  Modified by.......: 
********************************************************************
FUNCTION LaunchAppAndWait
LPARAMETERS tcCommandLine, tuFromDir, tcWindowMode

*     tcCommandLine               (R) - command line to launch
*     tuFromDir                    (O) - Run from directory (default - CWD)
*     tcWindowMode               (O)     - Start Application Window mode, one of (HIDE, MIN, MAX, NOR)
*                                          (default - default setting of application)

*     Returns:
*     0 = CreateProcess didn't start what was asked
*     1 = Process ran to completion
*     -1= Process started but user aborted wait.  Danger - app is still running AFAIK


IF TYPE('tcCommandLine') # 'C'
     *     Command line must be a character string
     RETURN 0
ENDIF

IF !lLoadedDlls
   DeclareDLLs() && Declare neccessary DLLs
ENDIF

IF TYPE('tuFromDir') # 'C'

     *     If not a character string, pass a null pointer, defaulting to Current Working Dir
     tuFromDir = 0

ELSE

     *     Otherwise, null pad the string
     tuFromDir = tuFromDir + CHR(0)

ENDIF
IF TYPE('tcWindowMode') # 'C'

     *     If not passed, set to null string
     tcWindowMode = ''

ELSE

     *     Translate the passed window mode to uppercase
     tcWindowMode = UPPER(tcWindowMode)

ENDIF

LOCAL nStartedProcessHandle, uResult, cProcessInfo, cStartUpInfo

*     Make default Structures for the CreateProcess call
*
*     ProcessInfo - 4 bytes, a Process handle, a Thread Handle, a (DWORD) ProcessId and a (DWORD) ThreadID
*                         we save the Process handle and return it to caller in tnReturnProcessHandle

cProcessInfo = REPL(CHR(0),16)

*     StartUpInfo is a 68 byte long complex structure;  we either have 68 bytes with a cb member (byte 1) 68
*     or with cb of 68, dwFlag low order byte (byte 45) of 1, and low order byte wShowWindow (byte 49) set to
*     the SW_ value appropriate for the Window Mode desired.

DO CASE
CASE tcWindowMode = 'HIDE'

     *     Hide - use STARTF_USESHOWFLAG and value of 0
     cStartUpInfo = CHR(68) + ;
                         REPL(CHR(0),43) + ;
                         CHR(1) + ;
                         REPL(CHR(0),23)

CASE tcWindowMode = 'NOR'

     *     Normal - use STARTF_USESHOWFLAG and value of 1
     cStartUpInfo = CHR(68) + ;
                         REPL(CHR(0),43) + ;
                         CHR(1) + ;
                         REPL(CHR(0),3) + ;
                         CHR(1) + ;
                         REPL(CHR(0),19)

CASE tcWindowMode = 'MIN'

     *     Minimize - use STARTF_USESHOWFLAG and value of 2
     cStartUpInfo = CHR(68) + ;
                         REPL(CHR(0),43) + ;
                         CHR(1) +  ;
                         REPL(CHR(0),3) + ;
                         CHR(2) + ;
                         REPL(CHR(0),19)

CASE tcWindowMode = 'MAX'

     *     Maximize - use STARTF_USESHOWFLAG and value of 3
     cStartUpInfo = CHR(68) + ;
                         REPL(CHR(0),43) + ;
                         CHR(1) +  ;
                         REPL(CHR(0),3) + ;
                         CHR(3) + ;
                         REPL(CHR(0),19)

*     Other options exist - see WINBASE.H for values

OTHERWISE

     *     Use default of application
     cStartUpInfo = CHR(68) + REPL(CHR(0),67)

ENDCASE

*     Do it now!
uResult = CrPr(     0, ;
                    tcCommandLine, ;
                    0, 0, 0, 0, 0, ;
                    tuFromDir, ;
                    @cStartUpInfo, ;
                    @cProcessInfo)

IF uResult = 1

     *     CreateProcess() started our app, but we have to wait until it finishes loading

     *     Strip the process handle from the PROCESS_INFORMATION structure

     nStartedProcessHandle = (((ASC(SUBST(cProcessInfo,4,1))*256) + ;
                                        ASC(SUBST(cProcessInfo,3,1)))*256 + ;
                                        ASC(SUBST(cProcessInfo,2,1)))*256 + ;
                                        ASC(LEFT(cProcessInfo,1))

     *     It's been launched;  wait until we're idling along

     =WaitInpIdle(GetCurrProc(),cnINFINITE)

     *     As long as the other process exists, wait for it

     DO WHILE WaitOnAppExit(nStartedProcessHandle, cnHalfASecond) = cnTimedOut

          *     Give us an out in case the other app hangs - lets the user quit via 
          IF INKEY() = 27
               *     Still running but we aren't waiting - return a -1 as a warning
               uResult = -1
               EXIT
          ENDIF

     ENDDO

ELSE

     *     Return 0 to indicate failure
     uResult = 0

ENDIF
RETURN uResult

******************************
Function DeclareDLLs
#DEFINE cnINFINITE           0xFFFFFFFF
#DEFINE cnHalfASecond     500     && milliseconds
#DEFINE cnTimedOut          0x0102

*     We need some API calls, declare here

*     GetCurrentProcess() returns the pseudohandle of the current process
DECLARE INTEGER GetCurrentProcess IN WIN32API AS GetCurrProc

*     WaitForIdleInput() waits until the target process is idle for input
DECLARE INTEGER WaitForInputIdle IN WIN32API AS WaitInpIdle ;
     INTEGER nProcessHandle, ;
     INTEGER nWaitForDuration

*     WaitForSingleObject() waits until the handle in parm 1 is signalled 
*     or the timeout period expires
DECLARE INTEGER WaitForSingleObject IN WIN32API AS WaitOnAppExit ;
     INTEGER hProcessHandle, ;
     INTEGER dwTimeOut

*     This API call does the work.  The parameters are as follows:
*          lpszModuleName - ptr-> file name of module to execute.  Since we aren't launching .CPLs, do not use
*          lpszCommandLine - ptr-> command to execute, as passed to us
*          lpSecurityAttributesProcess - ptr-> SECURITY_ATTRIBUTES structure for Process.  Pass a null pointer
*          lpSecurityAttributesThread - ptr-> SECURITY_ATTRIBUTES structure for first thread.  Pass a null pointer
*          bInheritHandles - whether or not chlid inherits parent handles.  Since no SECURITY_ATTRIBUTES passed, default to FALSE
*          dwCreateFlags - Process Creation Mode flag set.  We use the default mode at normal priority, ie 0
*          lpvEnvironment     - ptr-> a set of environment strings as if a MULTI_SZ.  We don't set, so pass a null pointer
*          lpszStartupDir - ptr-> the starting directory.  If none provided to us, pass a null pointer
*          lpStartInfo - ptr-> a STARTUPINFO structure.  We use one structure member at times.
*          lpProcessInfo - ptr-> a PROCESS_INFORMATION structure, used to return PID/PHANDLE detail.  
*                              We use one member on return
DECLARE SHORT CreateProcess IN WIN32API AS CrPr ;
     STRING lpszModuleName, ;
     STRING @lpszCommandLine, ;
     STRING lpSecurityAttributesProcess, ;
     STRING lpSecurityAttributesThread, ;
     SHORT bInheritHandles, ;
     INTEGER dwCreateFlags, ;
     STRING lpvEnvironment, ;
     STRING lpszStartupDir, ;
     STRING @lpStartInfo, ;
     STRING @lpProcessInfo

lLoadedDLLs=.t.
If it's not broken, fix it until it is.


My Blog
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform