Jak ukončit aplikaci "Čistě" v systému Win32

Překlady článku Překlady článku
ID článku: 178893 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

Souhrn

V ideálním případě procesu může požádat jiný proces, prostřednictvím některé Forma meziprocesové komunikace, vypnout. Nicméně pokud nemáte úroveň zdroje ovládání aplikace, které chcete vypnout, pak pravděpodobně nemáte tuto možnost. Přestože je zaručena "čistou" č způsobem, pokud chcete ukončit aplikaci v systému Win32, jsou kroky, které je možné provést zajistit, že aplikace bude používat nejlepší metodou pro čištění prostředky.

Další informace

32Bitové (a 16bitové procesy v systému Windows 95)

V prostředí Win32, slibuje vyčistit prostředky vlastněné operačního systému proces při jeho vypnutí. To, však neznamená, proces sám měl příležitost provést jakékoli konečné vyprázdnění informací disk libovolné konečné komunikaci prostřednictvím vzdáleného připojení, ani znamená že v procesu knihoven DLL budou mít příležitost k provedení jejich Kód PROCESS_DETACH. Z tohoto důvodu je obvykle vhodnější, aby se zabránilo ukončování aplikace v systému Windows 95 a Windows NT.

Pokud je to nezbytně nutné vypnout procesu, postupujte takto:
  1. Vystavit Funkce WM_CLOSE bude vlastníkem procesu, který chcete vypnout všechny oken nejvyšší úrovně. Mnoho aplikací systému Windows odpovědět na tuto zprávu vypnutí.

    POZNÁMKA:: Odpověď do aplikace konzoly funkce WM_CLOSE bude závisí, zda byl nainstalován popisovač řízení.

    Pomocí EnumWindows() táhla do cílového systému windows. Ve své funkci zpětného volání odpovídá zkontrolujte, pokud systému windows zpracovat ID procesu, který chcete vypnout. To lze provést voláním GetWindowThreadProcessId(). Po navázání odpovídající PostMessage() nebo SendMessageTimeout() k zaúčtování slouží funkce WM_CLOSE bude zpráva do okna.
  2. Čekání na popisovač procesu pomocí WaitForSingleObject(). Ujistěte se, že počkat s hodnotou časového limitu, protože existuje řada situací, ve kterých Funkce WM_CLOSE bude nevypne aplikace. Mějte na paměti dostatečně dlouhý časový limit (s WaitForSingleObject() nebo s SendMessageTimeout()) tak, aby uživatel mohl odpovídat na žádné dialogové okno pole, která byla vytvořena v odpověď na zprávu funkce WM_CLOSE bude.
  3. Pokud je vrácená hodnota je WAIT_OBJECT_0, pak aplikace zavřena sám čistě. Pokud je vrácená hodnota je WAIT_TIMEOUT, pak je nutné použít TerminateProcess() k ukončení aplikace.

    POZNÁMKA:: Getting3 vrácení hodnoty z jiných WaitForSingleObject() a WAIT_OBJECT_0 nebo WAIT_TIMEOUT, pomocí GetLastError() příčinu.
Pomocí následujících kroků, udělíte aplikaci nejvyšší možné pravděpodobnost vypnutí předchozího (kromě IPC nebo zásahu uživatele).

Problém 16 bitů (v systému Windows NT)

Předchozí kroky práce však pro 16bitové aplikace v systému Windows 95 Windows NT 16bitové aplikace pracovat velmi odlišně.

V systému Windows NT všechny 16bitové aplikace jsou spouštěny ve virtuální počítač DOS (VDM). Tento VDM je spuštěna jako Win32 procesu (NTVDM) v systému Windows NT. Prostředí NTVDM proces má ID procesu Můžete získat popisovač procesu prostřednictvím OpenProcess(), stejně jako můžete pomocí jiný proces pro Win32. Nicméně žádná z 16bitových aplikací spouštěných v VDM mají ID procesu, a proto nelze získat popisovač procesu z OpenProcess(). Všechny 16bitové aplikace VDM má popisovač 16bitové úlohy a 32bitové podproces provádění. Lze nalézt popisovač a podprocesu ID pomocí volání funkce VDMEnumTaskWOWEx(). Pro další informace naleznete v následujícím článku znalostí Microsoft Číselná soustava:
175030Jak vytvořit výčet aplikací v systému Win32
Vaše první a nejpřímější, možnost vypnutí 16 bitů aplikace v systému Windows NT je vypnutí celého procesu NTVDM. Jste lze to provést pomocí výše uvedených kroků. Potřebujete vědět Identifikátor procesu NTVDM (viz článek KB 175030 výše citované najít Identifikátor procesu NTVDM). Nevýhodou tohoto přístupu je, že slouží k zavření všech 16bitových aplikací spuštěných v tomto VDM. Pokud se jedná není vaším cílem, bude muset přijmout další přístup.

Chcete-li vypnout jediné 16bitové aplikace v rámci podsystému NTVDM proces, je nutné provést kroky jsou následující:
  1. Účtování systému windows, které jsou majetkem procesu funkce WM_CLOSE bude na všechny nejvyšší úrovně a mají stejný Identifikátor podprocesu vlastnící jako 16bitové úlohy, které chcete vypnete. Nejúčinnějším způsobem, jak to je pomocí EnumWindows(). Ve své funkci zpětného volání zkontrolujte-li v okně proces ID, a ID podprocesu odpovídá 16bitové úlohy, které chcete vypnout. Pamatujte, že ID procesu bude Identifikátor procesu v procesu NTVDM které je spuštěna 16bitová aplikace.
  2. Přestože ID podprocesu, máte nijak čekat ukončení procesu 16 bitů. Proto je nutné počkat libovolné délky časového (čisté vypnout dolů) a potom se pokuste žádost přesto systém ukončete. Pokud aplikace byl již ukončen. Dolů pak to bude Neprovádět žádnou akci. Pokud nebyl vypnut, pak budou ukončíte aplikaci.
  3. Ukončení aplikace využívající funkci nazvanou VDMTerminateTaskWOW(), které lze nalézt v Vdmdbg.dll. Trvá-li ID procesu podsystému VDM. a číslo úkolu 16bitové úlohy.
Tento přístup umožňuje vypnout v rámci jediné 16bitové aplikace VDM v systému Windows NT. 16Bitový systém Windows je však velmi dobře, čištění systémové prostředky ukončených úkolu a ani je WOWExec, v VDM. Pokud hledáte cleanest možný přístup k ukončení 16bitové aplikace v systému Windows NT, je třeba zvážit ukončení celého procesu VDM. Poznámka: Při spuštění 16 bitů aplikace, která může později ukončit a potom použít CREATE_SEPARATE_WOW_VDM s CreateProcess().

Ukázkový kód

Ukázkový kód implementuje metody popsané výše pro 16bitové a 32bitové bit aplikací pomocí následující dvě funkce: TerminateApp() a Terminate16App(). TerminateApp() trvá ID procesu 32bitové a časový limit (v miliseconds). Terminate16App(). Obě funkce použít explicitní propojení Knihovna DLL funguje tak, že budou kompatibilní s binární v systému Windows NT a Systém 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 ;
   }
				

Vlastnosti

ID článku: 178893 - Poslední aktualizace: 23. dubna 2011 - Revize: 4.0
Informace v tomto článku jsou určeny pro produkt:
Klíčová slova: 
kbhowto kbkernbase kbthread kbmt KB178893 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:178893

Dejte nám zpětnou vazbu

 

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