DetailPage-MSS-KB

Knowledge Base

Artikel ID: 178893 - Laatste beoordeling: vrijdag 23 september 2011 - Wijziging: 3.0

 

Op deze pagina

Samenvatting

In een ideale situatie kan het proces een ander proces, door enkele vragen vorm van interproces communicatie af te sluiten. Echter, als u geen besturings element bron niveau van de toepassing die u wilt afsluiten, vervolgens kan u deze optie niet beschikbaar. Hoewel er geen gegarandeerde "schone" manier om een Win32-toepassing afsluit, zijn de stappen die u kunt nemen om ervoor te zorgen dat de toepassing gebruikmaakt van de beste methode voor het opruimen van bronnen.

Meer informatie

32-Bits processen (en 16-bits processen onder Windows 95)

Onder Win32, belooft het besturings systeem voor het opschonen van de bronnen die eigendom zijn van een proces wanneer deze is afgesloten. Dit, echter, betekent niet dat het proces zelf heeft de mogelijkheid om te doen een definitieve Leegmaakacties van gegevens schijf, de laatste communicatie via een externe verbinding, noch betekent het dat het proces van DLL hebben de mogelijkheid voor het uitvoeren van hun PROCESS_DETACH code. Daarom is het meestal beter niet beëindiging van een toepassing onder Windows 95 en Windows NT.

Als u absoluut een proces afgesloten moet, gaat u als volgt te werk:
  1. Post een WM_CLOSE naar alle vensters op het hoogste niveau van eigendom is van het proces dat u wilt afsluiten. Veel Windows-toepassingen reageren op dit bericht door afgesloten.

    OPMERKING: Antwoord een console toepassing WM_CLOSE hangt af of deze handler voor een besturings element is geïnstalleerd.

    EnumWindows() gebruiken om de grepen voor uw doel vensters. Controleer als windows proces-ID in de callback-functie komt overeen met het proces dat u wilt afsluiten. U kunt dit doen door het aanroepen van GetWindowThreadProcessId(). Zodra u een overeenkomst hebt vastgesteld, gebruik PostMessage() of SendMessageTimeout() het WM_CLOSE-bericht naar het venster boeken.
  2. Gebruik WaitForSingleObject() om te wachten op de ingang van het proces. Zorg ervoor dat u met een time-outwaarde wachten omdat er veel situaties zijn waarin de WM_CLOSE wordt niet de toepassing afsluiten. Zorg ervoor dat de time-out lang genoeg (met WaitForSingleObject() of met SendMessageTimeout()) zodat een gebruiker kan reageren op alle dialoog vensters die zijn gemaakt in de WM_CLOSE-bericht.
  3. Als de retour waarde WAIT_OBJECT_0 is, vervolgens de toepassing afgesloten zelf schoon. Als de retour waarde WAIT_TIMEOUT is, moet u TerminateProcess() gebruiken om de toepassing af te sluiten.

    OPMERKING: Als u een retour waarde uit de WaitForSingleObject(), andere dan WAIT_OBJECT_0 of WAIT_TIMEOUT getting3, gebruik GetLastError () aanroepen om de oorzaak te bepalen.
De volgende stappen, geeft u de toepassing de best mogelijke kans afsluiten van duidelijke (afgezien van IPC of tussenkomst van de gebruiker).

Het probleem voor 16-bits (onder Windows NT)

De bovenstaande stappen werken echter voor 16-bits toepassingen onder Windows 95 Windows NT 16-bits toepassingen werkt heel anders.

Onder Windows NT, alle 16-bits toepassingen worden uitgevoerd in een virtuele DOS-machine (VDM). deze VDM als een Win32-proces (NTVDM) onder Windows NT wordt uitgevoerd. De NTVDM proces is een proces-id. Kunt u een greep aan het proces door middel van OpenProcess(), zoals u kunt met alle Win32-proces. Niettemin geen 16-bits toepassingen in het VDM hebben een proces-ID en daarom niet meer krijgt u een proces ingang van OpenProcess(). Elk 16-bits toepassingen in een VDM is een 16-bits taak verwerken en een 32-bits uitvoeringsthread. De ingang en thread-ID kan worden gevonden. via een aanroep van de functie VDMEnumTaskWOWEx(). Voor extra informatie, raadpleegt u het volgende artikel in de Microsoft Knowledge Basis:
175030  (http://support.microsoft.com/kb/175030/EN-US/ ) Het opsommen van Win32-toepassingen
De eerste en meest eenvoudige optie bij het afsluiten van een 16-bits onder Windows NT-toepassing is het hele NTVDM-proces afsluiten. U kan dit doen door de bovenstaande stappen te volgen. U hoeft alleen te weten de proces-ID van het NTVDM-proces (Zie het KB-artikel175030  (http://support.microsoft.com/kb/175030/EN-US/ ) hierboven de proces-ID van een NTVDM vinden). Het nadeel van deze aanpak is dat alle 16-bits toepassingen die worden uitgevoerd in die VDM gesloten. Als dit niet de bedoeling, en u moet een andere aanpak.

Als u een 16-bits toepassing binnen een NTVDM afsluiten proces, de volgende zijn de stappen die u moet uitvoeren:
  1. Een WM_CLOSE voor alle op het hoogste niveau die eigendom zijn van het proces windows boeken en hebben dezelfde eigenaar thread ID als het 16-bits-taak die u wilt afgesloten. De meest effectieve manier om dit te doen is met behulp van EnumWindows(). In de functie terugbellen controleren om te zien als het venster proces-ID en thread-ID overeenkomt met de 16-bits-taak die u wilt afsluiten. Vergeet niet dat de proces-ID is het verstandig om de proces-ID van het NTVDM-proces in dat de 16-bits toepassing wordt uitgevoerd.
  2. Een subproces-ID, maar u hebt geen manier om te wachten op de beëindiging van de 16-bits proces. Als gevolg hiervan moet wachten op een willekeurige tijds duur (voor een schone shut down) en vervolgens probeert te Sluit de toepassing toch af. Als de toepassing al afgesloten is. omlaag, vervolgens dit geen effect. Als deze nog niet afgesloten, vervolgens zal de toepassing afsluiten.
  3. De toepassing met een functie genaamd VDMTerminateTaskWOW(), beëindigen die kan worden gevonden in de Vdmdbg.dll. Duurt de proces-ID van het VDM en het nummer van de taak van de 16-bits-taak.
Deze benadering kunt u afsluiten met een 16-bits toepassing binnen een VDM onder Windows NT. 16-Bits Windows is echter niet zeer goed bij het reinigen bronnen van een taak beëindigd en geen van beide is de WOWExec uitgevoerd in het VDM. Als u op zoek bent naar de creëert mogelijke aanpak een 16-bits toepassing onder Windows NT wordt beëindigd, moet u overwegen de gehele VDM-proces wordt beëindigd. Opmerking: Als u een 16-bits toepassing die u mogelijk later beëindigen en vervolgens met de CREATE_SEPARATE_WOW_VDM met CreateProcess().

Voorbeeldcode

De voorbeeldcode implementeert de technieken beschreven voor 16-bits en 32- bits-toepassingen met behulp van de volgende twee functies: TerminateApp() en Terminate16App(). TerminateApp() heeft een 32-bits proces-ID en een time-out (in miliseconds). Terminate16App(). Beide functies gebruiken expliciete koppelen aan DLL functies zodat ze binair compatibel tussen Windows NT zijn en 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 ;
   }
				

De informatie in dit artikel is van toepassing op:
  • Microsoft Win32-API
Trefwoorden: 
kbhowto kbkernbase kbthread kbmt KB178893 KbMtnl
Machine-translated ArticleMachine-translated Article
BELANGRIJK: Dit artikel is vertaald door de vertaalmachine software van Microsoft in plaats van door een professionele vertaler. Microsoft biedt u professioneel vertaalde artikelen en artikelen vertaald door de vertaalmachine, zodat u toegang heeft tot al onze knowledge base artikelen in uw eigen taal. Artikelen vertaald door de vertaalmachine zijn niet altijd perfect vertaald. Deze artikelen kunnen fouten bevatten in de vocabulaire, zinsopbouw en grammatica en kunnen lijken op hoe een anderstalige de taal spreekt en schrijft. Microsoft is niet verantwoordelijk voor onnauwkeurigheden, fouten en schade ontstaan door een incorrecte vertaling van de content of het gebruik ervan door onze klanten. Microsoft past continue de kwaliteit van de vertaalmachine software aan door deze te updaten.
De Engelstalige versie van dit artikel is de volgende:178893  (http://support.microsoft.com/kb/178893/en-us/ )
Delen
Extra ondersteuningsopties
Microsoft Community Support-forums
Neem rechtstreeks contact met ons op
Een door Microsoft gecertificeerde partner zoeken
Microsoft Store