Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Acrobat/AcroRd.exe never kill process when closed
Message
From
22/03/2004 10:48:20
 
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Miscellaneous
Thread ID:
00888048
Message ID:
00888534
Views:
33
It worked four times in a row, and then stopped like waitforsingleobject. Very strange. Acrobat.exe remained running in all cases where it failed. I modified it slightly and it has not failed yet:
*--Requires Acrobat Reader 4 or 5
*--Requires registry.vcx and path stored to xregclass
*--Requires a .pdf form with the path included and stored in xacordform

xregclass = "c:\programnotes\registry.vcx"
xacordform = "C:\foxpro\vfp8\61nc.pdf"

DO declexewait
#Define ERROR_SUCCESS		0	&& OK
oReg = NEWOBJECT("FileReg",xregclass)
cAppKey = ""
cAppName = ""
m.cExtn = "PDF"
nErrNum = oReg.GetAppPath(m.cExtn,@cAppKey,@cAppName)
IF m.nErrNum # ERROR_SUCCESS
   MESSAGEBOX(C_EXTNOFOUND_LOC)
   RETURN
ENDIF
IF ATC(".EXE",m.cAppName) #0
   m.cAppName= ALLTRIM(SUBSTR(m.cAppName,1,ATC(".EXE",m.cAppName)+3))
   IF ASC(LEFT(cAppName,1))=34 &&check for long file name in quotes
      m.cAppName = SUBSTR(m.cAppName,2)
   ENDIF
ENDIF

lcACORDdef = SYS(5)+SYS(2003)
lnpos=(RAT("\",m.cAppName)+1)	&& one position to the right of
lcshort=''
lcpath=''
IF lnpos > 0
   lcshort = UPPER(SUBSTR(m.cAppName,lnpos))	&& grab from lnpos to end
   lcpath  = UPPER(LEFT(m.cAppname,RAT("\",m.cAppname)-1))
ENDIF
IF !EMPTY(lcshort) .and. !EMPTY(lcpath)
   lcpath = "'"+lcpath+"'"
   SET DEFAULT TO &lcpath
   llacordok = ExeWait(lcshort,xacordform,lcpath)
ENDIF
IF !llacordok
   =MESSAGEBOX("Unable Start Adobe.",0+16+4096,"ERROR")
ELSE
   WAIT WINDOW "Finished Displaying PDF Form" NOWAIT
ENDIF
SET DEFAULT TO &lcACORDdef
RETURN

*----------------------------------------------------------------------
*--Uses GetExitcodeProcess instead of waitforsingleobject
PROCEDURE  ExeWait (lcApp, lcCmdLine, lcdir)
IF _VFP.AutoYield = .F.
   llsetback = .T.
ELSE
   llsetback = .F.
ENDIF
 _VFP.AutoYield = .T.
#DEFINE INFINITE  0xFFFFFFFF
LOCAL lcStartupInfo, lcProcInfo, hProcess, ;
	lnPrio, lnIBelieve1
lnIBelieve1 = 1   && Don't remember what that was
lnPrio = 32 && Priority of Process=Normal
lcStartupInfo = CHR(68) + REPLI(CHR(0), 67)
lcProcInfo = REPLI(CHR(0), 16)
IF CreateProcess(0, m.lcApp+" "+m.lcCmdLine+CHR(0), 0,0,;
   m.lnIBelieve1, m.lnPrio,;
   0, 0, @lcStartupInfo, @lcProcInfo) <> 0
   * process and thread handles returned in ProcInfo structure
   hProcess = buf2dword(SUBSTR(lcProcInfo, 1,4))
   hThread = buf2dword(SUBSTR(lcProcInfo, 5,4))
   * waiting until the termination of the program
   DOEVENTS
   DO WHILE .T.
	exitcode = 0	&& initialize return value to 0
	= GetExitCodeProcess(hProcess, @exitcode)
	IF exitcode # 259	&& not still busy
  	   EXIT			&& fall out of loop
	ENDIF
	= Sleep (100)		&& wait .1 seconds
   ENDDO
   = CloseHandle(hThread)
   = CloseHandle(hProcess)
ELSE
   IF llsetback
      _VFP.AutoYield = .F.
   ENDIF
   RETURN .F.
ENDIF
IF llsetback
    _VFP.AutoYield = .F.
ENDIF
RETURN

PROCEDURE DECLexewait
DECLARE INTEGER CreateProcess IN kernel32;
	INTEGER lpAppName, STRING lpCmdLine, INTEGER lpProcAttr,;
	INTEGER lpThrAttr, INTEGER bInhHandles, INTEGER dwCrFlags,;
	INTEGER lpEnvir, INTEGER lpCurDir, ;
	STRING @lpStInfo, STRING @lpProcInfo
DECLARE INTEGER GetLastError IN kernel32
DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject
DECLARE INTEGER WaitForSingleObject IN kernel32;
	INTEGER hHandle, INTEGER dwMilliseconds
DECLARE INTEGER GetExitCodeProcess IN WIN32API INTEGER hProcess, INTEGER @lpExitCode
DECLARE Sleep IN kernel32 INTEGER dwMilliseconds
RETURN

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
RETURN
>>Seems to work great so far Michael. Thanks for testing this and finding a good solution! I really appreciate it... I'll be using it in tests for the next couple of weeks. I did some research on windows api functions but I never came across the getexitcodeprocess.
>>
>>Tracy
>>
>(SNIP)
>
>You're welcome, Tracy. This example raises a cloud of suspicion over the use of WaitForSingleObject from VFP. I presume that you tested it under VFP8 (I'm using VFP6). Fortunately, the GetExitCodeProcess workaround is a pretty simple general substitute. I'll be interested to see if anyone ever figures out why WaitForSingleObject didn't work in this case, or if similar problems arise with any applications other than Acrobat.
>
>Mike
.·*´¨)
.·`TCH
(..·*

010000110101001101101000011000010111001001110000010011110111001001000010011101010111001101110100
"When the debate is lost, slander becomes the tool of the loser." - Socrates
Vita contingit, Vive cum eo. (Life Happens, Live With it.)
"Life is not measured by the number of breaths we take, but by the moments that take our breath away." -- author unknown
"De omnibus dubitandum"
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform