Bạn hiện đang ngoại tuyến, hãy chờ internet để kết nối lại

Làm thế nào để chấm dứt một ứng dụng "Sạch" trong Win32

QUAN TRỌNG: Bài viết này được dịch bằng phần mềm dịch máy của Microsoft chứ không phải do con người dịch. Microsoft cung cấp các bài viết do con người dịch và cả các bài viết do máy dịch để bạn có thể truy cập vào tất cả các bài viết trong Cơ sở Kiến thức của chúng tôi bằng ngôn ngữ của bạn. Tuy nhiên, bài viết do máy dịch không phải lúc nào cũng hoàn hảo. Loại bài viết này có thể chứa các sai sót về từ vựng, cú pháp hoặc ngữ pháp, giống như một người nước ngoài có thể mắc sai sót khi nói ngôn ngữ của bạn. Microsoft không chịu trách nhiệm về bất kỳ sự thiếu chính xác, sai sót hoặc thiệt hại nào do việc dịch sai nội dung hoặc do hoạt động sử dụng của khách hàng gây ra. Microsoft cũng thường xuyên cập nhật phần mềm dịch máy này.

Nhấp chuột vào đây để xem bản tiếng Anh của bài viết này:178893
TÓM TẮT
Trong một thế giới hoàn hảo, quá trình của bạn có thể yêu cầu một tiến trình khác, thông qua một sốhình thức giao tiếp inter-process, tắt. Tuy nhiên, nếu bạn khôngcó nguồn cấp quyền kiểm soát của ứng dụng mà bạn muốn tắt,sau đó, bạn có thể không có tùy chọn này. Mặc dù có không có bảo đảm "sạch"cách để tắt ứng dụng trong Win32, có những bước mà bạn có thể mấtđể đảm bảo rằng các ứng dụng sử dụng các phương pháp tốt nhất để làm sạchtài nguyên.
THÔNG TIN THÊM

Quá trình 32-bit (và các quá trình 16-Bit dưới Windows 95)

Dưới Win32, hệ điều hành hứa hẹn để làm sạch các nguồn tài nguyên thuộc sở hữu của mộtquá trình khi nó tắt. Có điều này, tuy nhiên, nghĩa là quá trìnhriêng của mình đã có cơ hội để làm bất kỳ flushes cuối cùng của thông tin đểđĩa, bất kỳ giao tiếp chung kết qua một kết nối từ xa, và cũng không có nghĩa làmà trong quá trình của DLL sẽ có cơ hội để thực hiện của họPROCESS_DETACH mã. Đây là lý do tại sao nó là nói chung thích hợp hơn để tránhchấm dứt một ứng dụng theo Windows 95 và Windows NT.

Nếu bạn hoàn toàn phải tắt một quá trình, hãy làm theo các bước sau:
  1. Đăng một WM_CLOSE cho tất cả các cấp cao nhất windows thuộc sở hữu của quá trình mà bạn muốn tắt. Nhiều cửa sổ ứng dụng phản ứng thư này bằng cách tắt.

    LƯU Ý: Phản ứng một ứng dụng giao diện điều khiển để WM_CLOSE phụ thuộc vào việc có hay không nó đã cài đặt một bộ xử lý điều khiển.

    Sử dụng EnumWindows() để tìm các chốt để windows mục tiêu của bạn. Trong chức năng gọi lại của bạn, kiểm tra xem nếu các cửa sổ xử lý ID phù hợp với quá trình bạn muốn tắt. Bạn có thể làm điều này bằng cách gọi GetWindowThreadProcessId(). Một khi bạn đã thiết lập một trận đấu, sử dụng PostMessage() hoặc SendMessageTimeout() để gửi tin nhắn WM_CLOSE đến cửa sổ.
  2. Sử dụng WaitForSingleObject() để chờ cho xử lý của quá trình. Hãy chắc chắn rằng bạn chờ đợi với một giá trị timeout, bởi vì có rất nhiều tình huống mà trong đó WM_CLOSE sẽ không tắt ứng dụng. Hãy nhớ để làm cho thời gian chờ dài đủ (hoặc với WaitForSingleObject(), hoặc với SendMessageTimeout()) vì vậy mà người dùng có thể đáp ứng với bất kỳ hộp thoại hộp mà được tạo ra để đáp ứng với WM_CLOSE thư.
  3. Nếu giá trị trả lại là WAIT_OBJECT_0, sau đó đóng ứng dụng cửa chính nó sạch. Nếu giá trị trả lại là WAIT_TIMEOUT, sau đó bạn phải sử dụng TerminateProcess() để tắt ứng dụng.

    LƯU Ý: Nếu bạn getting3 một trở về giá trị từ WaitForSingleObject() khác sau đó WAIT_OBJECT_0 hoặc WAIT_TIMEOUT, sử dụng GetLastError() để xác định nguyên nhân.
Bằng cách làm theo các bước này, bạn cung cấp cho các ứng dụng tốt nhất có thể có mưađể tắt máy sạch (ngoài IPC hoặc người dùng can thiệp).

Vấn đề 16-Bit (dưới Windows NT)

Các bước trước làm việc cho các ứng dụng 16-bit dưới Windows 95, tuy nhiên,Ứng dụng Windows NT 16-bit làm việc rất khác nhau.

Dưới Windows NT, tất cả các ứng dụng 16-bit chạy trong máy DOS ảo(VDM). This VDM chạy như là một quá trình Win32 (NTVDM) theo Windows NT. NTVDMquá trình này có một quá trình của bạn. Bạn có thể có được một xử lý để xử lý thông quaOpenProcess(), giống như bạn có thể với bất kỳ quá trình Win32 khác.Tuy nhiên, không có ứng dụng 16-bit đang chạy trong VDM có mộtquá trình ID, và do đó bạn không thể có được một quá trình xử lý từOpenProcess(). Mỗi ứng dụng 16-bit trong một VDM đã một 16-bit xử lý tác vụvà một chủ đề 32-bit thực hiện. ID xử lý và chủ đề có thể được tìm thấythông qua một cuộc gọi đến chức năng VDMEnumTaskWOWEx(). Cho thêmthông tin, xin vui lòng xem các bài viết sau đây trong kiến thức MicrosoftCơ sở:
175030Làm thế nào để liệt kê các ứng dụng trong Win32
Của bạn lựa chọn đầu tiên, và đơn giản nhất, khi tắt một 16-bitứng dụng theo Windows NT là tắt toàn bộ quá trình NTVDM. Bạncó thể làm điều này bằng cách làm theo các bước được nêu ở trên. Bạn chỉ cần biếtID quá trình của quá trình NTVDM (xem bài viết KB 175030 trích dẫn ở trênđể tìm quá trình ID của một NTVDM). Nhược điểm của cách tiếp cận này lànó đóng tất cả các ứng dụng 16-bit đang chạy trong đó VDM. Nếu điều này làkhông mục tiêu của bạn, sau đó bạn cần phải thực hiện một cách tiếp cận.

Nếu bạn muốn tắt một ứng dụng 16-bit duy nhất trong một NTVDMquá trình, sau đây là các bước bạn cần phải thực hiện:
  1. Đăng một WM_CLOSE cho tất cả các cấp cao nhất windows mà được sở hữu bởi quá trình, và đó có cùng một owning thread ID như là nhiệm vụ 16-bit bạn muốn Dừng lại. Cách hiệu quả nhất để làm điều này là bằng cách sử dụng EnumWindows(). Trong chức năng gọi lại của bạn, kiểm tra xem nếu cửa sổ xử lý ID và Thread ID phù hợp với nhiệm vụ 16-bit bạn muốn tắt. Hãy nhớ rằng ID quá trình sẽ là quá trình ID của quá trình NTVDM trong ứng dụng 16-bit chạy.
  2. Mặc dù bạn có một ID thread, bạn không có cách nào để chờ đợi các chấm dứt quá trình 16-bit. Do đó, bạn phải đợi cho một tùy ý thời gian (để cho phép một sạch đóng xuống), và sau đó cố gắng tắt ứng dụng anyway. Nếu ứng dụng đã đóng xuống, sau đó điều này sẽ làm gì. Nếu nó đã không tắt, sau đó nó sẽ chấm dứt các ứng dụng.
  3. Chấm dứt các ứng dụng bằng cách sử dụng một chức năng gọi là VDMTerminateTaskWOW(), mà có thể được tìm thấy trong Vdmdbg.dll. Phải mất quá trình ID của VDM và nhiệm vụ số lượng đặc nhiệm 16-bit.
Cách tiếp cận này cho phép bạn tắt một ứng dụng 16-bit duy nhất trong vòng mộtVDM dưới Windows NT. Tuy nhiên, 16-bit cửa sổ không phải là rất tốt lúc làm sạchtài nguyên của một công việc chấm dứt, và không phải là WOWExec chạyVDM. Nếu bạn đang tìm kiếm các phương pháp có thể sạch đểchấm dứt một ứng dụng 16-bit dưới Windows NT, bạn nên xem xétchấm dứt toàn bộ quá trình VDM. Lưu Ý: Nếu bạn đang bắt đầu một 16-bitứng dụng mà bạn có thể chấm dứt sau này, sau đó sử dụng cácCREATE_SEPARATE_WOW_VDM với CreateProcess().

Mẫu mã

Mẫu mã thực hiện các kỹ thuật mô tả ở trên cho 16-bit và 32-chút ứng dụng bằng cách sử dụng hai chức năng sau đây: TerminateApp() vàTerminate16App(). TerminateApp() mất một ID quá trình 32-bit và một thời gian chờ(trong miliseconds). Terminate16App(). Cả hai chức năng sử dụng liên kết rõ ràng đểDLL chức năng do đó họ sẽ là tương thích nhị phân trên Windows NT vàWindows 95.
   //******************   //Header   //******************   #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 );   //******************   //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:      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 ;   }   /*----------------------------------------------------------------   DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread,                        WORD w16Task, DWORD dwTimeout )   Purpose:      Shut down a Win16 APP.   Parameters:      dwPID         Process ID of the NTVDM in which the 16-bit application is         running.      dwThread         Thread ID of the thread of execution for the 16-bit         application.      w16Task         16-bit task handle for the application.      dwTimeout         Wait time in milliseconds before shutting down the task.   Return Value:      If successful, returns TA_SUCCESS_16      If unsuccessful, returns TA_FAILED.      NOTE:  These values are defined in the header for this      function.   NOTE:      You can get the Win16 task and thread ID through the      VDMEnumTaskWOW() 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 ;   }				
Giết Exit chấm dứt chương trình ứng dụng quy trình công việc

Cảnh báo: Bài viết này đã được dịch tự động

Thuộc tính

ID Bài viết: 178893 - Xem lại Lần cuối: 09/23/2011 02:57:00 - Bản sửa đổi: 3.0

Microsoft Win32 Application Programming Interface

  • kbhowto kbkernbase kbthread kbmt KB178893 KbMtvi
Phản hồi