Ako ukončiť uplatňovanie "Čisto" v systéme Win32

Preklady článku Preklady článku
ID článku: 178893 - Zobraziť produkty, ktorých sa tento článok týka.
Rozbaliť všetko | Zbaliť všetko

Na tejto stránke

SUHRN

V dokonalom svete váš proces by mohol požiadať iný proces prostredníctvom niektoré forma vnútro-procesová komunikácia vypnúť. Avšak, ak nemáte mať zdroj riadenie aplikácie, ktorú chcete vypnúť, potom pravdepodobne nemáte túto možnosť. Hoci neexistuje bez garantovanej "čistý" cestu k vypnutiu žiadosť v systéme Win32, sú kroky, ktoré môžete vykonať aby sa zabezpečilo, že aplikácia používa najlepší spôsob čistenia zdroje.

DALSIE INFORMACIE

32-Bitové procesy (a 16-bitové procesy pod systémom Windows 95)

Podľa Win32, operačný systém sľubuje vyčistiť zdroje vo vlastníctve proces pri vypnutí. To, však neznamená že procesu sám má možnosť to urobiť žiadne konečné flushes informácií neznamená to ani disketa, každé konečné oznámenie cez pripojenie vzdialenej že v procese knižnice DLL bude mať príležitosť vykonať ich PROCESS_DETACH kód. To je dôvod, prečo je všeobecne vhodnejšie, aby sa zabránilo ktorým sa ukončuje žiadosť podľa systému Windows 95 a Windows NT.

Ak ste úplne vypnúť proces, postupujte nasledovne:
  1. Príspevok WM_CLOSE na všetky najvyššej úrovne windows vo vlastníctve proces, ktorý chcete vypnúť. Mnohých Windows aplikácií odpovedať na túto správu vypína.

    POZNÁMKA: Odpoveď aplikácia konzoly na WM_CLOSE závisí od toho, či má nainštalované popisovača riadenia.

    Použitie EnumWindows() nájsť rukoväte na vaše cieľové windows. V callback funkciou, zhoduje skontrolujte, ak windows' proces ID procesu, ktorý chcete vypnúť. Môžete to urobiť volaním GetWindowThreadProcessId(). Akonáhle ste stanovili zápas, použiť PostMessage() alebo SendMessageTimeout() na post WM_CLOSE správu do okna.
  2. Použite WaitForSingleObject() čakať na popisovač procesu. Uistite sa, že budete čakať s timeout hodnota, pretože existujú mnohé situácie, v ktorých WM_CLOSE nevypne uplatňovanie. Pamätať, dostatočne dlhý časový limit (s WaitForSingleObject() alebo s SendMessageTimeout()) tak, že používateľ môže reagovať na akékoľvek dialógové okno kolónky ktoré boli vytvorené v odpovedi na správu WM_CLOSE.
  3. Ak je vrátená hodnota WAIT_OBJECT_0, potom zatvorení aplikácie sama čisto. Ak je vrátená hodnota WAIT_TIMEOUT, musíte použiť TerminateProcess() na vypnutie aplikácie.

    POZNÁMKA: Ak ste getting3 vrátiť hodnotu z WaitForSingleObject() ostatné potom WAIT_OBJECT_0 alebo WAIT_TIMEOUT, pomocou GetLastError() určiť príčinu.
Pomocou týchto krokov, dáte uplatňovanie najlepšiu šancu na možné na vypnutie čisto (odhliadnuc od MPS alebo zásahu používateľa).

16-Bitové vydania (pod Windows NT)

Predchádzajúce kroky pracovať pre 16-bitové aplikácie pod systémom Windows 95, však Windows NT 16-bitových aplikácií pracovať veľmi odlišne.

Pod Windows NT všetkých 16-bitové aplikácie spustiť v virtuálny počítač DOS (VDM). Tento VDM beží ako procesu Win32 (NTVDM) pod Windows NT. NTVDM proces má proces ID. Môžete získať popisovač procesu prostredníctvom OpenProcess(), rovnako ako vy môžete s inými procesu systému Win32. Napriek tomu žiadne zo 16-bitovej aplikácie spustené v VDM nemá proces ID, a preto nemôže získať popisovač procesu z OpenProcess(). Každý 16-bitová aplikácia v VDM má 16-bitové úlohy popisovač a 32-bitové vlákno vykonávania. Rukoväť a vlákno ID možno nájsť prostredníctvom volanie funkcie VDMEnumTaskWOWEx(). Pre ďalšie informácie, prečítajte si nasledujúci článok v Microsoft Knowledge Číselná sústava:
175030Ako za účelom výberu aplikácií v systéme Win32
Váš prvý a najviac přímočaré možnosť, keď vypnutím 16-bitové žiadosti podľa systému Windows NT sa vypnúť celý proces NTVDM. Ste môžete to urobiť pomocou nasledujúcich krokov uvedených vyššie. Len potrebujete vedieť proces ID procesu NTVDM (pozri článok KB 175030 citovaný nájsť proces ID NTVDM). Nevýhodou tohto prístupu je, že Zavrie všetky 16-bitové aplikácie, ktoré bežia v tomto VDM. Ak je to nie váš cieľ, potom budete musieť prijať iný prístup.

Ak chcete vypnúť jeden 16-bitová aplikácia v rámci NTVDM procesu, tieto sú kroky musíte mať:
  1. Post WM_CLOSE na všetky najvyššej úrovne systému windows, ktoré sú vo vlastníctve procesu, a ktoré majú rovnaké vlastniaci vlákno ID ako 16-bitový úlohu, ktorú chcete vypnúť. Najúčinnejší spôsob, ako to urobiť je pomocou EnumWindows(). Vo vašej spätné volanie funkcie, skontrolujte v prípade v okne procesu ID, a vlákno ID zhoduje so 16-bitové úlohu, ktorú chcete vypnúť. Nezabudnite, že ID procesu bude proces ID procesu NTVDM v ktoré je spustená 16-bitová aplikácia.
  2. Hoci máte vlákno ID, máte žiadny spôsob, ako čakať na ukončenie procesu 16-bitový. Ako výsledok, musíte počkať svojvoľné dĺžka času (aby sa umožnilo čisté zavřel nadol), a potom skúste vypnúť uplatňovanie mimochodom. Ak uplatňovanie už má zavřel nadol, potom to bude nerobiť nič. Ak nebol vypnúť, potom bude ukončíte aplikáciu.
  3. Ukončiť uplatňovanie pomocou funkciu nazýva VDMTerminateTaskWOW(), ktoré možno nájsť v Vdmdbg.dll. Trvá proces ID VDM a úlohou číslo 16-bitové úlohy.
Tento prístup umožňuje vypnúť jeden 16-bitová aplikácia v rámci VDM pod Windows NT. Však 16-bitový systém Windows nie je veľmi dobré na čistenie zdrojov ukončené úlohu a ani je spustený v WOWExec VDM. Ak hľadáte cleanest prístup k ktorým sa ukončuje 16-bitová aplikácia pod Windows NT, mali by ste zvážiť ktorým sa ukončuje celý proces VDM. Poznámka: Ak ste začínajúci 16-bitové aplikácia, ktorá môže ukončiť neskôr, potom použite CREATE_SEPARATE_WOW_VDM s CreateProcess().

Vzorky kód

Vzorového kódu implementuje techniky uvedené vyššie pre 16-bitové a 32- bit aplikácie používajúce tieto dve funkcie: TerminateApp() a Terminate16App(). TerminateApp() berie 32-bitové proces ID a časový limit (v miliseconds). Terminate16App(). Obidve funkcie použiť výslovný odkaz na DLL funguje tak, že budú binárne kompatibilných cez 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 ;
   }
				
Note This is a "FAST PUBLISH" article created directly from within the Microsoft support organization. The information contained herein is provided as-is in response to emerging issues. As a result of the speed in making it available, the materials may include typographical errors and may be revised at any time without notice. See Terms of Use for other considerations.

Vlastnosti

ID článku: 178893 - Posledná kontrola: 18. októbra 2011 - Revízia: 2.0
Informácie v tomto článku sa týkajú nasledujúcich produktov:
  • Microsoft Win32 Application Programming Interface
Kľúčové slová: 
kbhowto kbkernbase kbthread kbmt KB178893 KbMtsk
Strojovo preložené
DÔLEŽITÉ: Tento článok bol preložený pomocou softvéru na strojový preklad od spoločnosti Microsoft, nie prekladateľom. Spoločnosť Microsoft ponúka články preložené prekladateľmi aj strojovo preložené články, vďaka čomu máte možnosť prístupu ku všetkým článkom databázy Knowledge Base vo svojom jazyku. Strojovo preložený článok však nie je vždy perfektný. Môže obsahovať chyby týkajúce sa slovnej zásoby, syntaxe alebo gramatiky, podobne ako cudzinec môže robiť chyby, keď rozpráva vašim jazykom. Spoločnosť Microsoft nenesie zodpovednosť za akékoľvek nepresnosti, chyby alebo škody spôsobené akýmkoľvek nepresným prekladom obsahu alebo jeho použitím zo strany zákazníkov. Spoločnosť Microsoft softvér na strojový preklad pravidelne aktualizuje.
Pokiaľ chcete vidieť anglickú verziu článku, kliknite sem:178893

Odošlite odozvu

 

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