青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

road420

導航

<2008年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

統計

常用鏈接

留言簿(2)

隨筆檔案

文章檔案

搜索

最新評論

閱讀排行榜

評論排行榜

如何“干凈地”終止 Win32 中的應用程序

如何“干凈地”終止 Win32 中的應用程序

編譯:Northtibet

  • 摘要
  • 32 位進程(和 Windows 95 下的 16 位進程)
  • 16 位問題(在 Windows NT 下)
  • 示例代碼
  • 摘要

      在理想環境中,某一進程可能會通過某種形式的進程間通信要求另一進程關閉。不過,如果你對希望其關閉的應用程序沒有源代碼級控制權,可能就沒有辦法做這樣的選擇。盡管沒有哪種方法能保證“干凈地”關閉 Win32 中的應用程序,但你可以采取一些步驟來確保應用程序使用最佳方法清除資源。

    32 位進程(和 Windows 95 下的 16 位進程)

      在 Win32 下,操作系統可保證在進程關閉時清除進程所擁有的資源。但是,這并不意味著進程本身將有機會對磁盤執行任何最后的信息刷新或通過遠程連接執行任何最后的通信,也不意味著進程的 DLL 將有機會執行其 PROCESS_DETACH 代碼。這就是通常最好避免在 Windows 95 和 Windows NT 下終止應用程序的原因。

    如果你必須關閉進程,請按照下列步驟操作:

    1. 向你打算關閉的進程所擁有的所有頂級窗口發送一條 WM_CLOSE 消息。許多 Windows 應用程序會通過關閉它自身來響應此消息。

      注意:控制臺應用程序對 WM_CLOSE 的響應取決于它是否安裝了控制處理程序。

      使用 EnumWindows() 找到目標窗口的句柄。在回調函數中,檢查該窗口的進程 ID 是否與要關閉的進程相匹配。你可以通過調用 GetWindowThreadProcessId() 來執行此操作。確定匹配項后,使用 PostMessage() 或 SendMessageTimeout() 向該窗口發送 WM_CLOSE 消息。
    2. 使用 WaitForSingleObject() 等待進程的句柄。確保你使用超時值等待,因為在很多情況下 WM_CLOSE 不會關閉應用程序。記住,應使超時值足夠長(通過 WaitForSingleObject() 或 SendMessageTimeout()),以便用戶可以響應為了 處理 WM_CLOSE 消息而創建的任何對話框。
    3. 如果返回值為 WAIT_OBJECT_0,則應用程序已干凈地將其自身關閉。如果返回值為 WAIT_TIMEOUT,則必須使用 TerminateProcess() 關閉應用程序。

      注意:如果從 WaitForSingleObject() 得到的返回值不是 WAIT_OBJECT_0 或 WAIT_TIMEOUT,則應使用 GetLastError() 找出原因。
    通過執行上述這些步驟,你便完全有可能干凈地關閉應用程序(無需 IPC 或用戶干預)。

    16 位問題(在 Windows NT 下)

      上述步驟適用于 Windows 95 下的 16 位應用程序,而 Windows NT 下的 16 位應用程序與 Windows 95 下的 16 位應用程序的工作方式差別非常大。
      在 Windows NT 下,所有 16 位應用程序都在虛擬 DOS 機 (VDM) 中運行。此 VDM 是作為 Windows NT 下的一個 Win32 進程 (NTVDM) 運行的。NTVDM 進程具有進程 ID。你可以通過 OpenProcess() 獲取該進程的句柄,就像處理其它任何 Win32 進程一樣。不過,在 VDM 中運行的 16 位應用程序都沒有進程 ID,因此你無法從 OpenProcess() 獲取進程句柄。VDM 中的每個 16 位應用程序都有一個 16 位任務句柄和一個 32 位執行線程。可通過調用函數 VDMEnumTaskWOWEx() 找到該任務句柄和線程 ID。有關這方面的其它信息,請參見:“如何用 Win32 APIs 枚舉應用程序窗口和進程”。
      關閉 Windows NT 下的 16 位應用程序的首選和最直接的方法是關閉整個 NTVDM 進程。你可以通過執行前面所描述的步驟來完成此操作。你只需知道 NTVDM 的進程 ID 即可,參考“如何用 Win32 APIs 枚舉應用程序窗口和進程”所講的方法來查找 NTVDM 的進程 ID。此方法的缺點是它會關閉在該 VDM 中運行的所有 16 位應用程序。如果這不是你想要的結果,則需要采取其它方法。
      如果你希望關閉 NTVDM 進程中的單個 16 位應用程序,需要按照下列步驟操作:
    1. 向該進程所擁有的以及與你要關閉的 16 位任務具有相同線程 ID 的所有頂級窗口發送一條 WM_CLOSE 消息。執行此操作最有效的方法是使用 EnumWindows()。在回調函數中,檢查窗口的進程 ID 和線程 ID 是否與要關閉的 16 位任務相匹配。請記住,該進程 ID 將成為在其中運行 16 位應用程序的 NTVDM 的進程 ID。
    2. 盡管你有線程 ID,但無法等待 16 位進程的終止。因此,你必須等待任意時間長度(以允許干凈關閉),然后嘗試關閉應用程序。如果應用程序已關閉,則此操作無效。如果應用程序尚未關閉,則它將終止應用程序。
    3. 使用稱為 VDMTerminateTaskWOW() 的函數終止應用程序,該函數可在 Vdmdbg.dll 中找到。它采用 VDM 的進程 ID 和 16 位任務的任務編號。

      此方法允許你關閉 Windows NT 下 VDM 中的單個 16 位應用程序。不過,16 位 Windows 以及 VDM 中運行的 WOWExec 都不能有效地清除已終止任務的資源。如果你要尋找最有可能干凈地終止 Windows NT 下的 16 位應用程序的方法,應考慮終止整個 VDM 進程。注意:如果你要啟動以后可能會終止的 16 位應用程序,請將 CREATE_SEPARATE_WOW_VDM 與 CreateProcess() 結合使用。

    示例代碼

      下面的示例代碼使用以下兩個函數實現上述用于 16 位和 32 位應用程序的方法:TerminateApp() 和 Terminate16App()。TerminateApp() 采用一個 32 位進程 ID 和一個超時值(以毫秒為單位)。Terminate16App()。這兩個函數都使用 DLL 函數的顯式鏈接,以便它們的二進制文件與 Windows NT 和 Windows 95 都兼容。

       //******************

    // 頭文件 TermApp.h

    //******************

    #include <windows.h>

    #define TA_FAILED 0

    #define TA_SUCCESS_CLEAN 1

    #define TA_SUCCESS_KILL 2

    #define TA_SUCCESS_16 3


    DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout ) ;

    DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread,

    WORD w16Task, DWORD dwTimeout );



    //*********************

    // 實現代碼 TermApp.cpp

    //*********************

    #include "TermApp.h"

    #include <vdmdbg.h>

    typedef struct

    {

    DWORD dwID ;

    DWORD dwThread ;

    } TERMINFO ;

    // 聲明回調枚舉函數.

    BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;

    BOOL CALLBACK Terminate16AppEnum( HWND hwnd, LPARAM lParam ) ;

    /*----------------------------------------------------------------

    DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )

    功能:

    關閉 32-位進程(或 Windows 95 下的 16-位進程)

    參數:

    dwPID

    要關閉之進程的進程 ID.

    dwTimeout

    進程關閉前等待的毫秒時間.

    返回值:

    TA_FAILED —— 如果關閉失敗.

    TA_SUCCESS_CLEAN —— 如果使用 WM_CLOSE 關閉了進程.

    TA_SUCCESS_KILL —— 如果使用 TerminateProcess() 關閉了進程.

    返回值的定義參見頭文件.

    ----------------------------------------------------------------*/

    DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )

    {

    HANDLE hProc ;

    DWORD dwRet ;

    // 如果無法用 PROCESS_TERMINATE 權限打開進程,那么立即放棄。

    hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,dwPID);

    if(hProc == NULL)

    {
    return TA_FAILED ;
    }


    // TerminateAppEnum() 將 WM_CLOSE 消息發到所有其進程ID 與你所提供的進程ID 匹配的窗口.

    EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;


    // 等待處理,如果成功,OK。如果超時,則干掉它.

    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 ;

    }


    /*----------------------------------------------------------------

    DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread,

    WORD w16Task, DWORD dwTimeout )

    功能:

    關閉 Win16 應用程序.

    參數:

    dwPID

    16-位程序運行其中的 NTVDM 進程 ID.

    dwThread

    16-位程序中執行線程的線程 ID.

    w16Task

    應用程序的 16-位任務句柄.

    dwTimeout

    任務關閉前等待的毫秒時間.



    返回值:

    如果成功, 返回 TA_SUCCESS_16

    如果不成功, 返回 TA_FAILED.

    返回值的定義參見該函數的頭文件.

    注意:

    你可以通過 VDMEnumTaskWOW() 或 VDMEnumTaskWOWEx() 函數獲得 Win16 和線程 ID.

    ----------------------------------------------------------------*/

    DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread,

    WORD w16Task, DWORD dwTimeout )

    {

    HINSTANCE hInstLib ;

    TERMINFO info ;

    // 你必須通過外部鏈接調用函數,以便代碼在所有 Win32 平臺上都兼容。

    BOOL (WINAPI *lpfVDMTerminateTaskWOW)(DWORD dwProcessId,WORD htask) ;

    hInstLib = LoadLibraryA( "VDMDBG.DLL" ) ;

    if( hInstLib == NULL )
    return TA_FAILED ;

    // 獲得函數過程地址.

    lpfVDMTerminateTaskWOW = (BOOL (WINAPI *)(DWORD, WORD ))

    GetProcAddress( hInstLib, "VDMTerminateTaskWOW" ) ;

    if( lpfVDMTerminateTaskWOW == NULL )

    {

    FreeLibrary( hInstLib ) ;

    return TA_FAILED ;

    }

    // 向所有匹配進程 ID 和線程的窗口發送 WM_CLOSE 消息.

    info.dwID = dwPID ;

    info.dwThread = dwThread ;

    EnumWindows((WNDENUMPROC)Terminate16AppEnum, (LPARAM) &info) ;

    // 等待.

    Sleep( dwTimeout ) ;

    // 然后終止.

    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 ;

    }

    posted on 2008-09-22 18:33 深邃者 閱讀(228) 評論(0)  編輯 收藏 引用

    青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品每日更新| 欧美午夜电影一区| 久久精品视频在线观看| 国产精品国产三级国产普通话蜜臀 | 在线亚洲免费| 黄色小说综合网站| 国产综合色精品一区二区三区| 国产片一区二区| 亚洲大片在线| 欧美伊人精品成人久久综合97| 一区二区三区四区五区精品| 亚洲成色777777女色窝| 欧美成人免费全部| 欧美chengren| 国产精品国产三级国产aⅴ无密码| 亚洲综合色激情五月| 亚洲欧美国产三级| 欧美.日韩.国产.一区.二区| 久久亚洲精品一区二区| 99视频精品| 久久伊人精品天天| 欧美精品久久99久久在免费线| 国内成人在线| 欧美aⅴ99久久黑人专区| 久久香蕉国产线看观看av| 亚洲女女做受ⅹxx高潮| 亚洲欧美成人在线| 欧美综合国产精品久久丁香| 在线亚洲美日韩| 欧美精品激情blacked18| 久久亚洲精品一区二区| 国产精品久久中文| 一区二区欧美国产| 一区二区三区不卡视频在线观看| 久久久久久高潮国产精品视| 国产伦精品一区二区三区| 一区二区高清在线观看| 久久久久国产精品午夜一区| 久久av免费一区| 亚洲视频一区在线| 欧美影院在线| 久久精品国语| 国产精品日韩欧美| 久久婷婷综合激情| 国产欧美日韩三区| 性欧美1819sex性高清| 激情欧美一区| 日韩视频一区二区三区在线播放免费观看 | 嫩模写真一区二区三区三州| 国内精品久久久久久久影视麻豆| 欧美一级夜夜爽| 中文欧美在线视频| 今天的高清视频免费播放成人| 亚洲欧美日韩第一区| 亚洲福利视频免费观看| 农村妇女精品| 一本色道久久综合狠狠躁篇怎么玩| 欧美极品一区二区三区| av不卡在线看| 亚洲免费一在线| 亚洲美女91| 亚洲精品美女| 国产欧美日韩高清| 久久综合图片| 亚洲精品一区二区三| 香蕉乱码成人久久天堂爱免费 | 欧美日韩在线播| 久久精品国产91精品亚洲| 亚洲清纯自拍| 久久综合网hezyo| 欧美在线看片| 香蕉久久夜色精品国产| 一区二区欧美视频| 最新成人av在线| 日韩五码在线| 欧美日韩国产一区二区三区| 亚洲经典一区| 欧美国内亚洲| 亚洲第一精品在线| 国产女主播一区二区| 国产精品一区二区女厕厕| 欧美色精品天天在线观看视频| 亚洲美女中出| 亚洲巨乳在线| 久久久www成人免费无遮挡大片 | 午夜久久影院| 欧美日本中文| 午夜精品美女久久久久av福利| 国产性色一区二区| 欧美在线影院在线视频| 久久gogo国模裸体人体| 久久成人精品一区二区三区| 欧美一区二区三区的| 国产亚洲综合精品| 欧美日本国产视频| 国产精品电影网站| 国产一区日韩一区| 亚洲欧洲日夜超级视频| 一区二区三区福利| 久久av老司机精品网站导航| 欧美不卡视频一区发布| 亚洲精品黄网在线观看| 久久久久久久久久久一区| 欧美成人午夜激情在线| 日韩一级精品| 亚洲欧美日本视频在线观看| 欧美一区二区在线视频| 麻豆国产精品va在线观看不卡| 六月天综合网| 久久精品国产一区二区三| 女女同性精品视频| 亚洲欧美日韩一区二区三区在线| 久久九九免费视频| 亚洲免费av观看| 久久国产欧美精品| 欧美午夜精品伦理| 在线中文字幕一区| 欧美高清日韩| 最新国产成人av网站网址麻豆 | 一区二区三区你懂的| 亚洲第一主播视频| 久久中文字幕一区二区三区| 亚洲人精品午夜| 欧美专区在线观看| 亚洲视频一二三| 国产精品成人观看视频国产奇米| 亚洲黄一区二区三区| 极品av少妇一区二区| 性欧美暴力猛交69hd| 久久精品99国产精品日本| 在线综合亚洲| 国产日韩在线播放| 午夜精品久久久99热福利| 国产精品99久久99久久久二8 | 久久久一本精品99久久精品66| 亚洲一区二区三区国产| 亚洲欧美www| 国产精品99久久久久久人| 国产欧美日韩亚洲精品| 亚洲视频综合| 激情五月综合色婷婷一区二区| 欧美成人一区二区在线| 欧美韩日一区二区三区| 欧美不卡一卡二卡免费版| 99国产精品久久久| 国产欧美日本| 亚洲日韩视频| 国内精品久久久久伊人av| 亚洲第一狼人社区| 国产一区二区三区久久悠悠色av | 亚洲在线观看| 欧美在线播放一区| 亚洲电影免费观看高清完整版在线 | 亚洲国产欧美久久| 亚洲国产成人av在线| 国产精品色婷婷| 亚洲精品永久免费| 久久久久久久高潮| 亚洲伊人观看| 欧美日韩卡一卡二| 欧美在线你懂的| 一本在线高清不卡dvd| 久久蜜桃精品| 老司机精品久久| 国产一区二区三区四区三区四| 99re热这里只有精品视频| 亚洲激情校园春色| 免费不卡亚洲欧美| 模特精品在线| 在线日韩中文| 免费av成人在线| 91久久午夜| 一区二区三区精品视频| 欧美精品一区二区在线播放| 亚洲国产精品视频一区| 久久久久国产成人精品亚洲午夜| 午夜精品理论片| 含羞草久久爱69一区| 久久青草久久| 日韩视频欧美视频| 欧美一级久久久| 国产精品高潮久久| 亚洲欧美在线看| 国产午夜精品久久久久久久| 午夜一区二区三区不卡视频| 久久欧美中文字幕| 一区二区日韩免费看| 国产亚洲在线观看| 久久国产高清| 欧美日韩久久精品| 久久久精品日韩| 一二三区精品| 欧美国产欧美综合| 久久成人精品| 亚洲永久免费精品| 亚洲三级视频在线观看| 欧美一区二区三区免费在线看| 久久精品人人做人人综合| 狠狠色狠狠色综合日日五| 久久久www成人免费无遮挡大片 |