Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Stopping a process
Message
De
11/07/2005 02:37:41
 
 
À
10/07/2005 11:14:12
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Versions des environnements
Visual FoxPro:
VFP 8 SP1
Divers
Thread ID:
01029879
Message ID:
01031099
Vues:
64
This message has been marked as the solution to the initial question of the thread.
>>>Hi All.
>>>
>>>I can use OpenProcess() and TerminateProcess() API function to kill a process. Does TerminateProcess() first attempt to close the process or does it just kill it? If the latter how can I first attempt to ask the process to exit gracefully?
>>>
>>>Thanks
>>
>>Jos,
>>
>>TerminateProcess() just kills it
>>
>>Maybe this helps
>>
>>How To Terminate an Application "Cleanly" in Win32 : http://support.microsoft.com/default.aspx?scid=kb;en-us;178893
>
>Hi Gregory. Thanks for the info which I had a look through. You wouldnt happen to have a ready bit of working code to send the WM_CLOSE message to a process PID would you?

Jos,

I have about the same code, without the need for the download.
I 've only added a function that goes through all the Top Level windows and extracts only those for a given processId
function do_it()

	?ProcessTerminate(1108, 5)
endfunc
*--------------------------------------------------------------------------
	
#define PROCESS_ALL_ACCESS (0x000F0000 + 0x00100000 + 0x0FFF)

#define WM_CLOSE                  0x0010

#DEFINE GW_HWNDFIRST  	0
#define	GW_HWNDNEXT	2
#define GW_OWNER	4
#define	GW_CHILD	5
#define GW_ENABLEDPOPUP 6

#define STATUS_WAIT_0				0x00000000
#define STATUS_ABANDONED_WAIT_0			0x00000080
#define STATUS_TIMEOUT				0x00000102


#define WAIT_FAILED			(-1)
#define	WAIT_OBJECT_0			STATUS_WAIT_0
#define	WAIT_ABANDONED			STATUS_ABANDONED_WAIT_0
#define WAIT_TIMEOUT                    STATUS_TIMEOUT

function ProcessTerminate(ProcessId, grace)

	declare long OpenProcess in win32api ;
			long dwDesiredAccess, integer bInheritHandle, long pid
	
	declare integer CloseHandle in win32api long Handle
		
	declare long WaitForSingleObject in win32api ;
			long handle, long MilliSeconds
	
	declare integer TerminateProcess in Kernel32.dll long, long
	declare integer PostMessage in user32.dll long, long, long, long
	
	declare long GetWindowThreadProcessId in user32.dll long, long@
	
	declare integer GetWindow in Win32API integer, integer 
	
	local Success
	Success = TRUE
	
	local ProcessHandle, WaitExitStatus
	local WindowArray[1], nWindowArray, i
	
	grace = iif(empty(m.grace), 5000, m.grace * 1000)
	
	do case
	case !m.Success
	
	otherwise
		ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, m.ProcessId)
	
	endcase
	
	do case
	case !m.Success
	
	case empty(m.ProcessHandle) && not there
		Success = FALSE
		assert FALSE
	
	otherwise
		= ProcessWindowList(m.ProcessId, @WindowArray, @nWindowArray)
		
		for i = 1 to m.nWindowArray
			=PostMessage(WindowArray[m.i], WM_CLOSE, 0, 0)
		endfor
	endcase
	
	do case
	case !m.Success
	
		
	otherwise
		WaitExitStatus = WaitForSingleObject(m.ProcessHandle, m.Grace)
		
		do case
		case m.WaitExitStatus = WAIT_OBJECT_0
			&& ok
		
		case m.WaitExitStatus = WAIT_FAILED
			pp=getlasterror()
			?LastError_Format(pp)
			assert FALSE
                        Success = FALSE
		
		case empty(m.WaitExitStatus) && gone
			assert FALSE
			
		case empty(TerminateProcess(m.ProcessHandle, 0))
			Success = FALSE
			assert FALSE
		
		otherwise
			?'forced'
		endcase
			
	endcase
	
	= empty(m.ProcessHandle) or !empty(CloseHandle(m.ProcessHandle))
	
	return m.Success
	
endfunc
*---------------------------------------------------------------------------
function LastError_Format(LastError)
	
	declare Integer FormatMessage in win32api ;
				Integer	dwFlags, ;
				string @lpSource, ;
				Integer	dwMessageId, ;
				Integer	dwLanguageId, ;
				string @lpBuffer, ;
				Integer nSize, ;
				Integer 
	
	local n, buf
	buf = space(1024)
	
	#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
	#define FORMAT_MESSAGE_IGNORE_INSERTS  0x00000200
	#define FORMAT_MESSAGE_FROM_STRING     0x00000400
	#define FORMAT_MESSAGE_FROM_HMODULE    0x00000800
	#define FORMAT_MESSAGE_FROM_SYSTEM     0x00001000
	#define FORMAT_MESSAGE_ARGUMENT_ARRAY  0x00002000
	#define FORMAT_MESSAGE_MAX_WIDTH_MASK  0x000000FF

	n = FormatMessage(	FORMAT_MESSAGE_FROM_SYSTEM, ;
						0, ;
						m.LastError, ;
						0, ;
						@m.buf, ;
						len(m.buf), ;
						0 ;
					  )
	
	local msg
	msg = 'Error ' + ltrim(str(m.LastError, 18, 0))
	do case
	case !empty(m.n)
		msg = m.msg + ' : ' + left(m.buf, m.n)
	endcase
	
	return m.msg

	#undefine FORMAT_MESSAGE_ALLOCATE_BUFFER
	#undefine FORMAT_MESSAGE_IGNORE_INSERTS
	#undefine FORMAT_MESSAGE_FROM_STRING
	#undefine FORMAT_MESSAGE_FROM_HMODULE
	#undefine FORMAT_MESSAGE_FROM_SYSTEM
	#undefine FORMAT_MESSAGE_ARGUMENT_ARRAY
	#undefine FORMAT_MESSAGE_MAX_WIDTH_MASK

endfunc
*-------------------------------------------------------------------------------
function ProcessWindowList(pid, WindowArray, nWindowArray)

	external array WindowArray
	
	nWindowArray = 0
	dime WindowArray[65000]

	=ProcessWindowList_(m.pid, @WindowArray, @m.nWindowArray, GetDesktopWindow())
	dime WindowArray[ max(1, m.nWindowArray) ]
	
endfunc
*-------------------------------------------------------------------------------
function ProcessWindowList_(pid, WindowArray, nWindowArray, hwnd)
	
	external array WindowArray
	
	local Handle, pidhwnd
	pidhwnd = 0
	
	Handle = GetWindow(m.hwnd, GW_CHILD)
	
	do while !empty(m.Handle)
		
		=GetWindowThreadProcessId(m.Handle, @m.pidhwnd )
		if( m.pidhwnd = m.pid )
			nWindowArray = m.nWindowArray + 1
			WindowArray[ m.nWindowArray ] = m.Handle
			
			&& uncomment for child windows
			*=ProcessWindowList_(m.pid, @WindowArray, @m.nWindowArray, m.Handle)
		endif
		

		Handle = GetWindow(m.Handle, GW_HWNDNEXT)
	enddo
endfunc
*-------------------------------------------------------------------------------
Gregory
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform