Remarks

The TerminateProcess function is used to unconditionally cause a process to exit. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather thanExitProcess.

This function stops execution of all threads within the process and requests cancellation of all pending I/O. The terminated process cannot exit until all pending I/O has been completed or canceled. When a process terminates, its kernel object is not destroyed until all processes that have open handles to the process have released those handles.

TerminateProcess is asynchronous; it initiates termination and returns immediately. If you need to be sure the process has terminated, call the WaitForSingleObject function with a handle to the process.

A process cannot prevent itself from being terminated.

 DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )

   Purpose:
      Shut down a 32-Bit Process (or 16-bit process under Windows 95)

   Parameters:
      dwPID
         Process ID of the process to shut down.

      dwTimeout
         Wait time in milliseconds before shutting down the process.

   Return Value:
      TA_FAILED - If the shutdown failed.
      TA_SUCCESS_CLEAN - If the process was shutdown using WM_CLOSE.
      TA_SUCCESS_KILL - if the process was shut down with
         TerminateProcess().
      NOTE:  See header for these defines.
   ----------------------------------------------------------------*/ 
   DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )
   {
      HANDLE   hProc ;
      DWORD   dwRet ;

      // If we can't open the process with PROCESS_TERMINATE rights,
      // then we give up immediately.
      hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,
         dwPID);

      if(hProc == NULL)
      {
         return TA_FAILED ;
      }

      // TerminateAppEnum() posts WM_CLOSE to all windows whose PID
      // matches your process's.
      EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;

      // Wait on the handle. If it signals, great. If it times out,
      // then you kill it.
      if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0)
         dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
      else
         dwRet = TA_SUCCESS_CLEAN ;

      CloseHandle(hProc) ;

      return dwRet ;
   }

BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam )
   {
      DWORD dwID ;

      GetWindowThreadProcessId(hwnd, &dwID) ;

      if(dwID == (DWORD)lParam)
      {
         PostMessage(hwnd, WM_CLOSE, 0, 0) ;
      }

      return TRUE ;
   }
 

Terminating a process has the following results:

Any remaining threads in the process are marked for termination.
Any resources allocated by the process are freed.
All kernel objects are closed.
The process code is removed from memory.
The process exit code is set.
The process object is signaled.

While open handles to kernel objects are closed automatically when a process terminates, the objects themselves exist until all open handles to them are closed. Therefore, an object will remain valid after a process that is using it terminates if another process has an open handle to it.

The GetExitCodeProcess function returns the termination status of a process. While a process is executing, its termination status is STILL_ACTIVE. When a process terminates, its termination status changes from STILL_ACTIVE to the exit code of the process.

When a process terminates, the state of the process object becomes signaled, releasing any threads that had been waiting for the process to terminate. For more about synchronization, see Synchronizing Execution of Multiple Threads.

When the system is terminating a process, it does not terminate any child processes that the process has created. Terminating a process does not generate notifications for WH_CBT hook procedures.

Use the SetProcessShutdownParameters function to specify certain aspects of the process termination at system shutdown, such as when a process should terminate relative to the other processes in the system.

How Processes are Terminated

A process executes until one of the following events occurs:

Any thread of the process calls the ExitProcess function. Note that some implementation of the C run-time library (CRT) call ExitProcess if the primary thread of the process returns.
The last thread of the process terminates.
Any thread calls the TerminateProcess function with a handle to the process.
For console processes, the default console control handler calls ExitProcess when the console receives a CTRL+C or CTRL+BREAK signal.
The user shuts down the system or logs off.

Do not terminate a process unless its threads are in known states. If a thread is waiting on a kernel object, it will not be terminated until the wait has completed. This can cause the application to stop responding.

The primary thread can avoid terminating other threads by directing them to call ExitThread before causing the process to terminate (for more information, see Terminating a Thread). The primary thread can still call ExitProcess afterwards to ensure that all threads are terminated.

The exit code for a process is either the value specified in the call to ExitProcess or TerminateProcess, or the value returned by the main or WinMain function of the process. If a process is terminated due to a fatal exception, the exit code is the value of the exception that caused the termination. In addition, this value is used as the exit code for all the threads that were executing when the exception occurred.

If a process is terminated by ExitProcess, the system calls the entry-point function of each attached DLL with a value indicating that the process is detaching from the DLL. DLLs are not notified when a process is terminated byTerminateProcess. For more information about DLLs, see Dynamic-Link Libraries.

If a process is terminated by TerminateProcess, all threads of the process are terminated immediately with no chance to run additional code. This means that the thread does not execute code in termination handler blocks. In addition, no attached DLLs are notified that the process is detaching. If you need to have one process terminate another process, the following steps provide a better solution:

Have both processes call the RegisterWindowMessage function to create a private message.
One process can terminate the other process by broadcasting a private message using theBroadcastSystemMessage function as follows:

 

 

	DWORD dwRecipients = BSM_APPLICATIONS;
	UINT uMessage = PM_MYMSG;
	WPARAM wParam = 0;
	LPARAM lParam = 0;

	BroadcastSystemMessage( 
		BSF_IGNORECURRENTTASK, // do not send message to this process
		&dwRecipients,         // broadcast only to applications
		uMessage,              // registered private message
		wParam,                // message-specific value
		lParam );              // message-specific value

The process receiving the private message calls ExitProcess to terminate its execution.

The execution of the ExitProcessExitThreadCreateThreadCreateRemoteThread, and CreateProcess functions is serialized within an address space. The following restrictions apply:

During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is finished for the process.
Only one thread at a time can be in a DLL initialization or detach routine.
The ExitProcess function does not return until there are no threads are in their DLL initialization or detach routines.

Excerpt:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686714(v=vs.85).aspx

http://support.microsoft.com/kb/178893

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686722(v=vs.85).aspx