Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Acrobat/AcroRd.exe never kill process when closed
Message
 
To
19/03/2004 16:04:13
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Miscellaneous
Thread ID:
00888048
Message ID:
00888113
Views:
36
This message has been marked as the solution to the initial question of the thread.
>When I start either Adobe Acrobat or Adobe Acrobat Reader using createprocess as in the code below, it starts fine. However, when I close either app (acrobat or reader), it appears that the process never ends under windows task manager so the waitforsingleobject never stops waiting. I have to go to windows task manager and kill the process for waitforsingleobject to stop waiting.
>
>Here is my code that anyone can run. All it requires is:
>
>1. Acrobat Reader be installed
>2. Registry.vcx and the path to it stored in xregclass var.
>3. A .PDF form with the path included stored in xacordform var.
>
>I'm wondering if anyone else can duplicate it? It does it everytime to me...
>
>
>*--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"    && modify for your system
>xacordform = "C:\foxpro\vfp8\61nc.pdf"        && modify for your system
>
>DO decl
>#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
>llacordok = .F.
>IF !EMPTY(lcshort) .and. !EMPTY(lcpath)
>   lcpath = "'"+lcpath+"'"
>   SET DEFAULT TO &lcpath
>   llacordok = RunAndWait(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
>
>
>
>PROCEDURE  RunAndWait (lcApp, lcCmdLine, lcdir)
>#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
>	= WaitForSingleObject(hProcess, INFINITE)
>	= CloseHandle(hThread)
>	= CloseHandle(hProcess)
>ELSE
>	RETURN .F.
>ENDIF
>RETURN
>
>PROCEDURE DECL
>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
>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
>
>
Tracy,

I was also able to reproduce this strange behavior on my XP Pro SP1 machine. It seems that the problem has something to do with the call to WaitForSingleObject, and I'm not sure what the issue is with this. However, I found a simple alternative using instead the following method of waiting:
do while .t.
	exitcode = 0					&& initialize return value to 0
	= GetExitCodeProcess(hProcess, @exitcode)	&& try to obtain process exit code
	if exitcode # 259				&& not still busy
		exit					&& fall out of loop
	endif
	= Sleep (100)					&& wait .1 seconds
enddo
with the following additional declarations:
DECLARE INTEGER GetExitCodeProcess IN WIN32API INTEGER hProcess, INTEGER @lpExitCode
DECLARE Sleep IN kernel32 INTEGER dwMilliseconds 
Mike
Montage

"Free at last..."
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform