在 Win32 下,操作系統(tǒng)可保證在進(jìn)程關(guān)閉時清除進(jìn)程所擁有的資源。但是,這并不意味著進(jìn)程本身將有機(jī)會對磁盤執(zhí)行任何最后的信息刷新或通過遠(yuǎn)程連接執(zhí)行任何最后的通信,也不意味著進(jìn)程的 DLL 將有機(jī)會執(zhí)行其 PROCESS_DETACH 代碼。這就是通常最好避免在 Windows 95 和 Windows NT 下終止應(yīng)用程序的原因。
如果您必須關(guān)閉進(jìn)程,請按照下列步驟操作:
1.
向您要關(guān)閉的進(jìn)程所擁有的所有頂級窗口發(fā)送一條 WM_CLOSE 消息。許多 Windows 應(yīng)用程序會通過關(guān)閉它自身來響應(yīng)此消息。
此方法允許您關(guān)閉 Windows NT 下 VDM 中的單個 16 位應(yīng)用程序。不過,16 位 Windows 以及 VDM 中運(yùn)行的 WOWExec 都不能有效地清除已終止任務(wù)的資源。如果您要尋找最有可能干凈地終止 Windows NT 下的 16 位應(yīng)用程序的方法,應(yīng)考慮終止整個 VDM 進(jìn)程。注意:如果您要啟動以后可能會終止的 16 位應(yīng)用程序,請將 CREATE_SEPARATE_WOW_VDM 與 CreateProcess() 結(jié)合使用。
示例代碼
下面的示例代碼使用以下兩個函數(shù)實(shí)現(xiàn)上述用于 16 位和 32 位應(yīng)用程序的方法:TerminateApp() 和 Terminate16App()。TerminateApp() 采用一個 32 位進(jìn)程 ID 和一個超時值(以毫秒為單位)。Terminate16App()。這兩個函數(shù)都使用 DLL 函數(shù)的顯式鏈接,以便它們的二進(jìn)制文件與 Windows NT 和 Windows 95 都兼容。 //******************//Header//******************#include <windows.h>#define TA_FAILED 0#define TA_SUCCESS_CLEAN 1#define TA_SUCCESS_KILL 2#define TA_SUCCESS_16 3DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout ) ;DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread,WORD w16Task, DWORD dwTimeout );//******************//Source//******************#include "TermApp.h"#include <vdmdbg.h>typedef struct{DWORD dwID ;DWORD dwThread ;} TERMINFO ;// Declare Callback Enum Functions.BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;BOOL CALLBACK Terminate16AppEnum( HWND hwnd, LPARAM lParam ) ;/*----------------------------------------------------------------DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )Purpose:Shut down a 32-Bit Process (or 16-bit process under Windows 95)Parameters:dwPIDProcess ID of the process to shut down.dwTimeoutWait 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 withTerminateProcess().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);elsedwRet = TA_SUCCESS_CLEAN ;CloseHandle(hProc) ;return dwRet ;}/*----------------------------------------------------------------DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread,WORD w16Task, DWORD dwTimeout )Purpose:Shut down a Win16 APP.Parameters:dwPIDProcess ID of the NTVDM in which the 16-bit application isrunning.dwThreadThread ID of the thread of execution for the 16-bitapplication.w16Task16-bit task handle for the application.dwTimeoutWait time in milliseconds before shutting down the task.Return Value:If successful, returns TA_SUCCESS_16If unsuccessful, returns TA_FAILED.NOTE: These values are defined in the header for thisfunction.NOTE:You can get the Win16 task and thread ID through theVDMEnumTaskWOW() or the VDMEnumTaskWOWEx() functions.----------------------------------------------------------------*/DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread,WORD w16Task, DWORD dwTimeout ){HINSTANCE hInstLib ;TERMINFO info ;// You will be calling the functions through explicit linking// so that this code will be binary compatible across// Win32 platforms.BOOL (WINAPI *lpfVDMTerminateTaskWOW)(DWORD dwProcessId,WORD htask) ;hInstLib = LoadLibraryA( "VDMDBG.DLL" ) ;if( hInstLib == NULL )return TA_FAILED ;// Get procedure addresses.lpfVDMTerminateTaskWOW = (BOOL (WINAPI *)(DWORD, WORD ))GetProcAddress( hInstLib, "VDMTerminateTaskWOW" ) ;if( lpfVDMTerminateTaskWOW == NULL ){FreeLibrary( hInstLib ) ;return TA_FAILED ;}// Post a WM_CLOSE to all windows that match the ID and the// thread.info.dwID = dwPID ;info.dwThread = dwThread ;EnumWindows((WNDENUMPROC)Terminate16AppEnum, (LPARAM) &info) ;// Wait.Sleep( dwTimeout ) ;// Then terminate.lpfVDMTerminateTaskWOW(dwPID, w16Task) ;FreeLibrary( hInstLib ) ;return TA_SUCCESS_16 ;}BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ){DWORD dwID ;GetWindowThreadProcessId(hwnd, &dwID) ;if(dwID == (DWORD)lParam){PostMessage(hwnd, WM_CLOSE, 0, 0) ;}return TRUE ;}BOOL CALLBACK Terminate16AppEnum( HWND hwnd, LPARAM lParam ){DWORD dwID ;DWORD dwThread ;TERMINFO *termInfo ;termInfo = (TERMINFO *)lParam ;dwThread = GetWindowThreadProcessId(hwnd, &dwID) ;if(dwID == termInfo->dwID && termInfo->dwThread == dwThread ){PostMessage(hwnd, WM_CLOSE, 0, 0) ;}return TRUE ;}
返回頁首
這篇文章中的信息適用于:
?
Microsoft Win32 Application Programming Interface (API)當(dāng)用于