Welcome To The Home Of The Visual FoxPro Experts  
home. signup. forum. archives. search. google. articles. downloads. faq. members. weblogs. sponsors. rss.
 From: Carlos Alloatti
  Where is Carlos Alloatti?
 
 Argentina
 Carlos Alloatti
 To: Markus Raab
  Where is Markus Raab?
 Bad Kötzting
 Germany
 Markus Raab
 Tags
Subject: RE: Control Process
Thread ID: 201250 Message ID: 201266 # Views: 39 # Ratings: 0
Version: Visual FoxPro 9 SP2 Category: Win32API programming
Date: Saturday, November 01, 2008 5:14:12 PM         
   


> Hello,
>
>
> in my program (let's call: MAIN.EXE) i start a second programm (let's call: second.exe) with the run command. The problem now is, that my user can start my programm (=MAIN) several times. The second program can take about 2 minutes to finish - if the user starts my program MAIN during this 2 minutes again, the second program (SECOND) will also start for a second time, third time and s.o. ....
>
> If i'm looking in the windows task manager, i can see the processes - how can i check, if the process SECOND.EXE is still running ?
>
> Many thanks
>
>
> Markus

*!* _IsProgramRunning.prg

*!* returns 0 if the specified exe is not running
*!* returns > 0 if the specified exe is running (the process ID)
*!* returns -1 if there was an error
*!* See also _SetForegroundProcess

#Define PROCESS_QUERY_INFORMATION	0x400
#Define PROCESS_VM_READ				0x10
#Define MAX_PATH					260

Lparameters pcFileName As String

Local ;
	lnLen, ;
	lnBytesReturned, ;
	lcProcessIds, ;
	lnResult, ;
	lcProcessArray, ;
	lnReturnValue, ;
	lnCurrentProcessId, ;
	lnProcessID, ;
	lnProcessHandle, ;
	lcFileName, ;
	lnIndex

If Vartype(m.pcFileName) # "C" Then
	m.pcFileName = Application.ServerName
Endif

If Empty(Justext(m.pcFileName)) Then
	m.pcFileName = Forceext(m.pcFileName, "exe")
Endif

*!* First get an array of running processes IDs:

*!* "It is a good idea to use a large array, because it is hard to
*!* predict how many processes there will be at the time you call EnumProcesses."

*!*	To determine how many processes were enumerated, divide the pBytesReturned value
*!*	by sizeof(DWORD). There is no indication given when the buffer is too small to
*!*	store all process identifiers. Therefore, if pBytesReturned equals cb, consider
*!*	retrying the call with a larger array.

*!* processes array buffer, 256 bytes will fit 64 processes
m.lnLen = 256

*!* This will tell us how many bytes the api call returned:
m.lnBytesReturned = m.lnLen

Do While m.lnLen = m.lnBytesReturned
	m.lcProcessIds = Replicate(Chr(0), m.lnLen)
	m.lnResult = _apiEnumProcesses(@m.lcProcessIds,  m.lnLen, @m.lnBytesReturned)
	If m.lnResult = 0 Then
		Exit
	Endif
	m.lnLen = m.lnLen * 2
Enddo

If m.lnResult = 0 Then
	*!* We failed to enumerate the processes
	Return -1
Endif

*!* Trim buffer:
m.lcProcessArray = Left(m.lcProcessIds, m.lnBytesReturned)

m.lnReturnValue = 0
m.lnCurrentProcessId = _apiGetCurrentProcessId()

*!* Now scan the running procesess IDs array:
For m.lnIndex = 1 To m.lnBytesReturned Step 4

	m.lnProcessID = CToBin(Substr(m.lcProcessArray, m.lnIndex, 4), "4rs")

	*!* If this is the process id of this actual program, just skip it:
	If m.lnProcessID =  m.lnCurrentProcessId Then
		Loop
	Endif

	*!* Try to get a handle to the process:
	m.lnProcessHandle = _apiOpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, 0, m.lnProcessID)

	*!* If we could not open this process, just try the next process:
	If m.lnProcessHandle = 0 Then
		Loop
	Endif

	*!* Now get the process file name:
	m.lnLen = MAX_PATH
	m.lcFileName = Replicate(Chr(0), m.lnLen)

	m.lnResult = _apiGetModuleFileNameEx(m.lnProcessHandle, 0, @m.lcFileName, m.lnLen)

	*!* Now free the process handle:
	_apiCloseHandle(m.lnProcessHandle)

	*!* If we could net get the process name, just try the next process:
	If m.lnResult = 0 Then
		Loop
	Endif

	m.lcFileName = Left(m.lcFileName, m.lnResult)
	
	If Upper(Justfname(m.pcFileName)) == Upper(Justfname(m.lcFileName)) Then
		m.lnReturnValue = m.lnProcessID
		*!* If we found our module, just exit now:
		Exit
	Endif

Endfor

Return m.lnReturnValue


*!* _apiEnumProcesses.prg

Lparameters lpidProcess, cb, cbNeeded

Declare Integer EnumProcesses In psapi.Dll As _apiEnumProcesses ;
	String  @lpidProcess,;
	Integer cb,;
	Integer @cbNeeded
Return _apiEnumProcesses(@m.lpidProcess, m.cb, @m.cbNeeded)


*!* _apiGetCurrentProcessId.prg

Declare Integer GetCurrentProcessId In win32api As _apiGetCurrentProcessId
Return _apiGetCurrentProcessId()

*!* _apiOpenProcess.prg

Lparameters dwDesiredAccess, bInheritHandle, dwProcessId

Declare Integer OpenProcess In win32api As _apiOpenProcess ;
	Integer dwDesiredAccess,;
	Integer bInheritHandle,;
	Integer dwProcessId
Return _apiOpenProcess(m.dwDesiredAccess, m.bInheritHandle, m.dwProcessId)

*!* _apiGetModuleFileNameEx.prg

Lparameters hProcess, hModule, lpFileName, nSize

Declare Integer GetModuleFileNameEx In psapi.Dll As _apiGetModuleFileNameEx ;
	Integer hProcess,;
	Integer hModule,;
	String  @lpFilename,;
	Integer nSize
Return _apiGetModuleFileNameEx(m.hProcess, m.hModule, @m.lpFileName, m.nSize)

*!* _apiCloseHandle.prg

Lparameters hObject
Declare Integer CloseHandle In win32api As _apiCloseHandle ;
	Integer hObject
Return _apiCloseHandle(m.hObject)


To make the above code work, save each code snippet in its own prg using the name specified in the comments. (Mike Yearwood style)

---
Carlos Alloatti



COMPLETE THREAD
Control Process Posted by Markus Raab @ 11/1/2008 2:15:00 PM
RE: Control Process Posted by Frank Cazabon @ 11/1/2008 2:23:17 PM
RE: Control Process Posted by Yousfi Benameur @ 11/1/2008 2:33:51 PM
RE: Control Process Posted by Markus Raab @ 11/2/2008 10:19:31 AM
RE: Control Process Posted by Yousfi Benameur @ 11/2/2008 1:35:56 PM
RE: Control Process Posted by Carlos Alloatti @ 11/1/2008 5:14:12 PM