Win32 では「クリーン」アプリケーションを終了する方法

文書翻訳 文書翻訳
文書番号: 178893
すべて展開する | すべて折りたたむ

目次

概要

完璧な世界では、いくつかの他のプロセスがプロセスを求めることがあります。シャット ダウン、プロセス間の通信のフォームです。ただし、有効でない場合シャット ダウンする、アプリケーションのソース レベルの制御がある、このようなオプションがあります。「クリーン」保証なしWin32 でアプリケーションを停止するには、あるための手順アプリケーションがクリーンアップを行うために最適な方法を使用することを確認するのにはリソース。

詳細

32 ビット プロセス (および Windows 95 の 16 ビット プロセス)

Win32 では、によって所有されているリソースをクリーンアップするのには、オペレーティング システムを約束します。プロセスのシャット ダウン時します。これは、しかしがどういうこと、最後のフラッシュへの情報のためにビジネス ・ チャンスがされています。は、リモート接続を介した通信はすべて最終的なディスクも意味してそのプロセスの DLL を実行することが、PROCESS_DETACH コードです。これを回避する勧めです。Windows 95 と Windows NT の下でアプリケーションを終了しています。

絶対プロセス ダウンをシャット ダウンする必要がある場合は、次の手順を実行します。
  1. シャット ダウン、プロセスが所有するすべてのトップレベル ウィンドウに、WM_CLOSE を転記します。多くの Windows アプリケーションがシャット ダウンして対処します。

    メモコントロールのハンドラーを取り付けたかどうかに関係なくの WM_CLOSE を: コンソール アプリケーションの応答に依存します。

    EnumWindows() を使用して、ターゲット ウィンドウへのハンドルを検索します。コールバック関数では、windows のプロセス ID とを確認してくださいシャット ダウン プロセスを検索します。これは、GetWindowThreadProcessId() を呼び出すことによって実行できます。一致を確立すると、PostMessage() または SendMessageTimeout() を使用してウィンドウに WM_CLOSE メッセージを投稿します。
  2. WaitForSingleObject() を使用して、プロセスのハンドルを待機するします。多くの状況で、WM_CLOSE をアプリケーションを終了しないため、タイムアウト値を待つかどうかを確認します。十分な長さのタイムアウトを確認する必要があります (WaitForSingleObject()、または SendMessageTimeout()) のいずれか任意のダイアログ ボックスには、ユーザーが応答できるようにするには、ボックスには、WM_CLOSE メッセージへの応答として作成されました。
  3. WAIT_OBJECT_0、戻り値の場合は、アプリケーション自体が閉じる。戻り値が WAIT_TIMEOUT の場合は、アプリケーションをシャット ダウンするには TerminateProcess() を使用する必要があります。

    メモ: 戻り値の WaitForSingleObject() の WAIT_OBJECT_0、または WAIT_TIMEOUT から getting3 場合は、原因を特定する GetLastError() を使用します。
次の手順に従って、アプリケーション最適な可能性のある可能性をによりシャット ダウン IPC またはユーザーの介入以外から明確。

16 ビットの問題 ([Windows NT)

ただし Windows 95 の 16 ビット アプリケーションを上記の手順を使用、Windows NT 16 ビット アプリケーションは非常に異なる方法で動作します。

Windows NT では、すべての 16 ビット アプリケーションは仮想 DOS マシンで実行します。(VDM). Windows NT の下の Win32 プロセス (NTVDM) としてこの VDM を動作します。NTVDMプロセスは、プロセス ID を持つプロセスを通じてのハンドルを取得することができます。その他の Win32 プロセスで OpenProcess() と同様、ことができます。それでもの VDM で実行している 16 ビット アプリケーションが、プロセス ID、およびプロセスのハンドルを取得できませんのでOpenProcess()。各 16 ビット アプリケーションを VDM で 16 ビットのタスクの処理があります。32 ビットの実行のスレッドをします。ハンドルとスレッド ID があります。VDMEnumTaskWOWEx() 関数への呼び出しをします。追加情報は、マイクロソフト サポート技術情報の次の資料を参照してくださいベース:
175030Win32 アプリケーションを列挙するには、方法
16 ビットをシャット ダウンするとき、最初と最も直接的なオプションWindows NT でアプリケーションは、NTVDM プロセス全体をシャット ダウンします。、これは、上記の手順に従って実行できます。だけ知っておくべきNTVDM プロセスのプロセス ID (KB 資料を参照してください 175030 上記の引用NTVDM プロセス ID を検索する)。このアプローチの欠点はその VDM で実行されているすべての 16 ビット アプリケーションを閉じます。この場合はない目標をし、別の方法を使用する必要があります。

場合は、NTVDM 内で 1 つの 16 ビット アプリケーションをシャット ダウンします。プロセスは、以下の手順を実行する必要がありますです。
  1. WM_CLOSE をするすべての最上位には、プロセスが所有している windows 投稿、所有している同じスレッド ID を 16 ビット タスクとして認識されてシャット ダウンします。これを行うには最も効果的な方法は EnumWindows() を使用してです。コールバック関数では、ウィンドウのプロセス ID とを確認し、シャット ダウンする 16 ビット タスクのスレッド ID を検索します。注意してください。プロセス ID は、NTVDM プロセスのプロセス ID になります16 ビット アプリケーションを実行しています。
  2. スレッド ID を持っていますがが待機する方法あるありませんが16 ビットのプロセスを終了します。したがって、待つ必要があります、任意の期間 (が正しくシャット ダウンするため)、ししてみてくださいアプリケーションをシャット ダウンします。場合は、アプリケーションが既にシャット ダウンダウン、これ何も起こりません。シャット ダウンされていない場合は、しますアプリケーションを終了します。
  3. VDMTerminateTaskWOW() 呼び出される関数を使用して、アプリケーションを終了します。Vdmdbg.dll に存在します。VDM のプロセス ID を取得します。16 ビット タスクのタスク数とします。
この方法で 1 つの 16 ビット アプリケーションをシャット ダウンすることができます、VDM で Windows NT。ただし、16 ビット Windows クリーンアップで非常に良いではありません。終了したタスクでは、どちらのリソースの実行中に、WOWExec のです。VDM。業界は、可能なアプローチを探している場合は、Windows NT の下で、16 ビット アプリケーションを終了して、検討する必要があります。VDM プロセス全体が終了します。注: 16 ビットを起動している場合アプリケーションは、その後終了し、使用する可能性があります、CREATE_SEPARATE_WOW_VDM CreateProcess() を使用します。

サンプル コード

サンプル コード 16 ビットと 32 ビットの上記の手法を実装します。ビットは、次の 2 つの関数を使用するアプリケーション: TerminateApp() とTerminate16App()。TerminateApp() は、32 ビットのプロセス ID とは、タイムアウトを受け取る(ミリ秒 () で)。Terminate16App()。どちらの関数も明示的なリンクを使用します。DLL 関数は、バイナリ互換性のある Windows NT の間でされるようにし、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 ;
   }
				

プロパティ

文書番号: 178893 - 最終更新日: 2011年7月5日 - リビジョン: 4.0
キーワード:?
kbhowto kbthread kbkernbase kbmt KB178893 KbMtja
機械翻訳の免責
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:178893
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。

フィードバック

 

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