Jak zakończyć aplikację "Czysto" w systemie Win32

Tłumaczenia artykułów Tłumaczenia artykułów
Numer ID artykułu: 178893 - Zobacz jakich produktów dotyczą zawarte w tym artykule porady.
Rozwiń wszystko | Zwiń wszystko

Na tej stronie

Streszczenie

W idealnych procesu może zwrócić inny proces, za pomocą niektórych Forma komunikacji międzyprocesowej, aby zamknąć. Jednakże w przeciwnym razie kontrolę poziomu aplikacji, która ma zostać zamknięty, następnie może nie mieć tej opcji. Chociaż istnieje nr gwarantowana "czysty" sposób, aby zamknąć aplikację w systemie Win32, są kroki, które można wykonać Aby zapewnić, że aplikacja używa najlepszą metodę oczyszczania zasoby.

Więcej informacji

Procesy 32-bitowe (i procesy 16-bitowe w systemie Windows 95)

W podsystemie Win32, system operacyjny przyrzeka oczyścić zasoby własnością proces, podczas zamykania. Nie, jednak oznacza to że proces sam miał możliwość wykonaj wszelkie końcowe opróżnienia informacji dysku wszelkie końcowe komunikacji za pośrednictwem połączenia zdalnego ani oznacza z tego procesu bibliotek DLL będą mieli możliwość wykonywania ich Kod PROCESS_DETACH. Dlatego lepiej unikać Zakończenie aplikacji w systemie Windows 95 i Windows NT.

Jeśli bezwzględnie należy zamknąć procesu, wykonaj następujące kroki:
  1. Księgowanie polecenie WM_CLOSE zostało posiadane przez proces, który chcesz zamknąć wszystkich okien najwyższego poziomu. Wiele aplikacji systemu Windows odpowiada na tę wiadomość przez zamknięcie.

    UWAGA: Aplikacja konsoli odpowiedzi na polecenie WM_CLOSE zostało zależy od tego, czy nie został zainstalowany program obsługi sterowania.

    Znajdź dojścia do okien docelowych przy użyciu EnumWindows(). W funkcja wywołania zwrotnego zaznacz, jeśli system windows przetwarza identyfikator dopasowuje procesu, który ma być zamknięty. Można to zrobić przez wywołanie GetWindowThreadProcessId(). Po ustanowieniu dopasowania umożliwia PostMessage() lub SendMessageTimeout() ogłosić wiadomość polecenie WM_CLOSE zostało do okna.
  2. Poczekaj, aż dojście procesu za pomocą WaitForSingleObject(). Upewnij się, że wartością limitu czasu oczekiwania, ponieważ istnieje wiele sytuacji, w których polecenie WM_CLOSE zostało nie wyłączy aplikacji. Należy pamiętać o wystarczająco długo, limit czasu (wraz z WaitForSingleObject() lub z SendMessageTimeout()) tak, aby użytkownik mógł odpowiadać na wszystkie okna dialogowe pól, które zostały utworzone w odpowiedzi na polecenie WM_CLOSE zostało wiadomości.
  3. Jeśli wartość zwracana jest WAIT_OBJECT_0, następnie aplikacja zamknięty sam czysto. Jeśli wartość zwracana jest WAIT_TIMEOUT, należy użyć TerminateProcess(), aby zamknąć aplikację.

    UWAGA: Getting3 wartość zwrotu z WaitForSingleObject() innych, a następnie WAIT_OBJECT_0 lub WAIT_TIMEOUT, użyć polecenia GetLastError() przy wymaganym do ustalenia przyczyny.
Wykonując następujące kroki, udzielić aplikacji najlepsze możliwe ryzyko zamknięcia bezpośrednio (oprócz IPC lub interwencji użytkownika).

16-Bitowe wydania (w systemie Windows NT)

Poprzednie kroki dla 16-bitowych aplikacji w systemie Windows 95 działają jednak Windows NT 16-bitowych aplikacji działają bardzo różnie.

W systemie Windows NT wszystkie aplikacje 16-bitowe uruchomione w wirtualnej maszynie DOS (VDM). VDM ta jest wykonywana jako proces systemu Win32 (NTVDM) w systemie Windows NT. NTVDM proces ma identyfikator procesu. Można uzyskać dojścia do procesu za pomocą OpenProcess(), podobnie jak można się z innym procesem Win32. Jednakże żadne aplikacje 16-bitowe uruchomione w VDM posiada Identyfikator procesu, a zatem nie można pobrać uchwytu procesu z OpenProcess(). Każdej aplikacji 16-bitowych VDM ma obsługiwać zadania 16-bitowe i 32-bitowe wątku wykonywania. Identyfikator dojścia i Wątek można znaleźć poprzez wywołanie funkcji VDMEnumTaskWOWEx(). Dla dodatkowych informacje, zobacz następujący artykuł w wiedzy firmy Microsoft Podstawy:
175030Jak wyliczanie aplikacji w systemie Win32
Pierwszy i najprostsza, opcję użytkownika podczas zamykania 16-bitowe aplikacji w systemie Windows NT jest zamknięty w całym procesie NTVDM. W przypadku Można to zrobić, wykonaj czynności opisane powyżej. Trzeba znać Identyfikator procesu w procesie NTVDM (zobacz artykuł KB 175030 cytowana powyżej Aby znaleźć identyfikator procesu NTVDM). Wadą poziomu tego podejścia jest Zamyka go wszystkie aplikacje 16-bitowe uruchomione w tym VDM. Jeśli jest to nie gracza, a następnie użytkownik musi podejmować inne podejście.

Jeśli chcesz zamknąć pojedynczej aplikacji 16-bitowych w procesie NTVDM. proces, jakie należy podjąć kroki są następujące:
  1. Księgowanie systemu windows, będące własnością procesu, polecenie WM_CLOSE zostało do wszystkich najwyższego poziomu i które mają ten sam identyfikator wątek będący właścicielem jako zadanie 16-bitowych, które chcesz Zamknij system. Jest najbardziej skutecznym sposobem, aby to zrobić przy użyciu EnumWindows(). Z funkcji wywołania zwrotnego Sprawdź Jeśli okno procesu identyfikator, i Identyfikator wątku reprezentuje zadanie 16-bitowych, które chcesz zamknąć. Należy pamiętać, że Identyfikator procesu ma być identyfikator procesu w procesie NTVDM w którego działa aplikacja 16-bitowych.
  2. Chociaż identyfikator wątku jest sposobem oczekiwanie na Zakończenie procesu 16-bitowych. W efekcie trzeba poczekać, dowolnego długość czasu (aby umożliwić czystego zamknięcia w dół), a następnie spróbuj Mimo to zamknąć aplikację. Jeśli aplikacja już spowodował zamknięcie w dół następnie ten nie powoduje żadnych skutków. Jeśli nie został zamknięty, następnie będzie ono zakończyć działanie aplikacji.
  3. Zakończyć działanie aplikacji przy użyciu funkcji o nazwie VDMTerminateTaskWOW(), co można znaleźć w Vdmdbg.dll. Pobiera identyfikator procesu VDM. i numer zadania zadania 16-bitowych.
To podejście umożliwia zamykanie pojedynczej aplikacji 16-bitowych w ciągu VDM w systemie Windows NT. 16-Bitowego systemu Windows nie jest jednak bardzo dobra na czyszczenie zasobów zakończonych zadań i nie jest WOWExec w VDM. Jeśli szukasz cleanest podejście do Zakończenie aplikacji 16-bitowych w systemie Windows NT, należy rozważyć Zakończenie cały proces VDM. Uwaga: Jeśli uruchamiasz 16-bitowe Aplikacja, która może zakończyć później, następnie w Flagę CREATE_SEPARATE_WOW_VDM z CreateProcess().

Przykładowy kod

Przykładowy kod implementuje technik opisanych powyżej 16-bitowe i 32- bit aplikacji przy użyciu następujących dwóch funkcji: TerminateApp() i Terminate16App(). TerminateApp() pobiera identyfikator procesu 32-bitowe i limit czasu (w miliseconds). Terminate16App(). Obie funkcje za pomocą jawnych łączenie do Biblioteka DLL działa tak, będą one binarne zgodny w systemie Windows NT i System 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 ;
   }
				

Właściwości

Numer ID artykułu: 178893 - Ostatnia weryfikacja: 23 września 2011 - Weryfikacja: 3.0
Informacje zawarte w tym artykule dotyczą:
  • Microsoft Win32 Application Programming Interface
Słowa kluczowe: 
kbhowto kbkernbase kbthread kbmt KB178893 KbMtpl
Przetłumaczone maszynowo
WAŻNE: Ten artykuł nie został przetłumaczony przez człowieka, tylko przez oprogramowanie do tłumaczenia maszynowego firmy Microsoft. Firma Microsoft oferuje zarówno artykuły tłumaczone przez ludzi, jak i artykuły tłumaczone maszynowo, dzięki czemu każdy użytkownik może uzyskać dostęp do całej zawartości bazy wiedzy Knowledge Base we własnym języku. Prosimy jednak pamiętać, że artykuły przetłumaczone maszynowo nie zawsze są doskonałe. Mogą zawierać błędy słownictwa, składni i gramatyki, przypominające błędy robione przez osoby, dla których język użytkownika nie jest językiem ojczystym. Firma Microsoft nie odpowiada za wszelkie nieścisłości, błędy lub szkody spowodowane nieprawidłowym tłumaczeniem zawartości oraz za wykorzystanie tej zawartości przez klientów. Oprogramowanie do tłumaczenia maszynowego jest często aktualizowane przez firmę Microsoft.
Anglojęzyczna wersja tego artykułu to:178893

Przekaż opinię

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com