Nasıl yapılır: "temiz bir şekilde" Win32, uygulamayı Sonlandır

Makale çevirileri Makale çevirileri
Makale numarası: 178893 - Bu makalenin geçerli olduğu ürünleri görün.
Hepsini aç | Hepsini kapa

Bu Sayfada

Özet

Ideal şartlar altında başka bir işlem, bazı kapanması için işlemler arası iletişim için formu aracılığıyla işleminizin sorun. Kapatmak istediğiniz uygulamayı kaynak düzeyindeki kontrolü yoksa, ancak sonra bu seçeneği sunulmayabilir. Win32'de bir uygulamanın kapatmaya garantili "temiz" yolu olsa da, kaynakları temizleme için uygulamanın en iyi yöntemi kullanmasını sağlamak için uygulayabileceğiniz adımları vardır.

Daha fazla bilgi

32 Bitlik işlemler (ve 16 bitlik işlemler Windows 95 altında)

Win32'in altında işletim sistemi bunu kapatıldığında bir işlem tarafından sahip olunan kaynaklar temizlemek taahhüt. Bu ancak, işlem kendisini diske, bir uzak bağlantı üzerinden herhangi bir son iletişim bilgileri, herhangi bir son temizleme yapmak için fırsatın aldığını ve bunu, işlemin geliyor gelmez, DLL, PROCESS_DETACH kod yürütmek için fırsatınız vardır. Bu, Windows 95 ve Windows NT altında uygulama sonlandırılıyor önlemek için genellikle tercih olduğu neden olur.

Bir işlemi kesinlikle kapatmanız gerekir, şu adımları izleyin:
  1. Bir WM_CLOSE tüm üst düzey pencereleri kapatmak istediğiniz işlemin sahibi için deftere nakledin. Birçok Windows uygulaması tarafından kapatılıyor, bu iletiye yanıt.

    Not: Denetim işleyici olmadığı yüklü olduğu BIR konsol uygulamasının yanıt WM_CLOSE bağlıdır.

    EnumWindows() için hedef pencerelerinizi tanıtıcıları bulmak için kullanın. Geri arama işlevinizin denetleyin Wındows KIMLIĞI işlemek, kapatmak istediğiniz işlemi eşleşir. GetWindowThreadProcessId() ça??rarak bunu yapabilirsiniz. Bir eşleşme kurulmuş bir kez PostMessage() veya SendMessageTimeout() WM_CLOSE ileti penceresine deftere nakletmek için kullanın.
  2. Işlemin tanıtıcı için beklenecek WaitForSingleObject() kullanın. WM_CLOSE uygulama kapatmayacaktır birçok durum olduğundan bir zaman aşımı değeri, beklemeniz dikkat edin. Zaman aşımı tıklatmanıza yetecek kadar uzun süre yapmak, anımsamak (WaitForSingleObject() veya SendMessageTimeout()) kullanıcı herhangi bir iletişim kutusuna yanıt verebilir böylece kutuları, WM_CLOSE iletiye yanıt olarak oluşturuldu.
  3. Dönüş değeri WAIT_OBJECT_0, sonra uygulama kendisini temiz bir şekilde kapandı. Dönüş değeri, WAIT_TIMEOUT ise, uygulamayı kapatmak için TerminateProcess() kullanmanız gerekir.

    Not: bir dönüş değeri WaitForSingleObject() diğer sonra WAIT_OBJECT_0 veya WAIT_TIMEOUT getting3 ise, GetLastError() nedenini belirlemek için kullanın.
Bu adımları izleyerek, uygulama olası en iyi olasılığı kapatma temiz bir şekilde (sayılmazsa IPC veya kullanıcı katılımı) verdiğiniz.

16-Bit sorunun altında (Windows NT)

Önceki çalışma için 16 bit uygulamalar Windows 95 altında olan adımları, ancak Windows NT 16 bit uygulamalar bir çok farklı çalışır.

Windows NT altında tüm 16 bit uygulamalar, bir sanal DOS makinesi (VDM) içinde çalışır. Bu bir VDM, Windows NT altında bir Win32 işlem (NTVDM) çalışır. NTVDM işleminde, bir işlem KIMLIğI vardır. Diğer bir Win32 işlemine gibi OpenProcess(), işlemi için bir tanıtıcı elde edebilirsiniz. Yine de, hiç bir VDM içinde çalışan 16 bit uygulamaların işlem KIMLIĞI vardır ve bu nedenle, tanıtıcı bir işlem OpenProcess() alamıyor. Her bir VDM 16 bit uygulama görev tanıtıcı bir 16-bit ve 32-bit yürütme iş parçacığı vardır. Tanıtıcı ve iş parçacığı KIMLIĞI ile VDMEnumTaskWOWEx() işlevine bir çağrı bulunabilir. Ek bilgi için lütfen Microsoft Knowledge Base'de aşağıdaki makaleye bakın:
175030Nasıl yapılır: Win32 uygulamaları numaralandır
Windows NT altında bir 16 bit uygulama kapatma tüm NTVDM işlemi kapatmak için ilk ve en basit seçeneğinizi. Yukarıda anlatılan adımları izleyerek bunu yapabilirsiniz. NTVDM işlemi işlem KIMLIĞI bilmeniz yeterlidir (bir NTVDM işlemi KIMLIĞINI bulmak için yukarıdaki bildirilmiş KB makale 175030 bakın). Bu yaklaşımın downside bu VDM içinde çalışan tüm 16 bit uygulamalar kapanmadan ' dir. Bu, amacınız değilse, başka bir yaklaşım olması gerekir.

Tek bir 16 bit uygulama içinde bir NTVDM işlemi kapatmaya isterseniz atmanız gereken adımlar şunlardır:
  1. Bir WM_CLOSE işlem tarafından ait olan ve aynı sahip iş parçacığı KIMLIĞI olarak kapanması için istediğiniz 16 bit görevi olan tüm üst düzey pencereleri için deftere nakledin. Bunu yapmak için en etkili yolu, EnumWindows() kullanmaktır. Geri arama işlevinde, pencerenin işlem KIMLIĞI ve iş parçacığı KIMLIĞI 16 bit görevi kapatmak istiyor eşleşip eşleşmediğini denetleyin. Işlem KIMLIĞI 16 bit uygulama çalıştığı NTVDM işlemi işlem KIMLIĞI olarak gittiği unutmayın.
  2. Bir iş parçacığı KIMLIĞI vardır, ancak <a0>16-bit</a0> işleminin sona erdirme beklenecek yolu vardır. Sonuç olarak, bir rasgele süreyi (temiz bir bilgisayarı izin vermek için <a0></a0>) bekleyin ve sonra uygulama yine de bilgisayarı deneyin gerekir. Uygulama zaten kapatıldı, sonra hiçbir şey bunu yapar. Bu bilgisayarı alamadım, uygulama sonlandırılacak.
  3. Vdmdbg.dll içinde bulunan VDMTerminateTaskWOW() adlı bir işlevini kullanan uygulama sonlandırın. VDM 16 bit görevi görev sayısı ve işlem KIMLIĞI alıyor.
Bu yaklaşım, Windows NT altında bir VDM tek bir 16 bit uygulama kapatmasına izin verir. Ancak, 16-bit Windows kaynakları görevin sona erdirilen temizlemeyi en çok iyi ve ne VDM içinde çalışan WOWExec ' dir. Windows NT altında bir 16 bit uygulama sonlandırılıyor için cleanest olası yaklaşım arıyorsanız, tüm VDM işlemi sonlandırma düşünmelisiniz. Not: bir 16 bit uygulama daha sonra sonlandırabilirsiniz başlatıyorsanız, sonra CREATE_SEPARATE_WOW_VDM CreateProcess() ile kullanın.

Örnek kod

Örnek kod, aşağıdaki iki işlevi kullanma 16-bit ve 32-bit uygulamalar için yukarıda teknikleri uygular: TerminateApp() ve Terminate16App(). TerminateApp(), 32-bit işlem KIMLIĞI ve bir zaman aşımı (miliseconds içinde) alır. Terminate16App(). Windows NT ve Windows 95 arasında ikili uyumlu yüklenebilmesi açık DLL işlevleri için bağlama iki işlevlerini kullanın.
   //******************
   //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 ;
   }
				

Özellikler

Makale numarası: 178893 - Last Review: 13 Temmuz 2004 Salı - Gözden geçirme: 2.4
Bu makaledeki bilginin uygulandığı durum:
  • Microsoft Win32 Uygulama Programlama Arabirimi, Ne zaman ne ile kullanilir:
    • Microsoft Windows 95
    • Microsoft Windows NT 4.0
    • the operating system: Microsoft Windows 2000
    • the operating system: Microsoft Windows XP
Anahtar Kelimeler: 
kbmt kbhowto kbkernbase kbthread KB178893 KbMttr
Machine-translated Article
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:178893

Geri Bildirim Ver

 

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