curve   製品情報  |   検索  |   サポート  |   フィードバック  |  ホーム  
Microsoft Japan ホーム

[SDK32]Win32 でアプリケーションを列挙する方法

最終更新日: 1998/02/18
文書番号: J041632


この資料は以下について記述したものです。

  • 次の環境で動作する Microsoft(R) Win32(R) Application Programming Interface(API)
      - Microsoft(R) Windows NT(R) 4.0
      - Microsoft(R) Windows(R) 95
    
    
この資料は、米国 Microsoft Corporation から提供されている Knowledge Base の Article ID Q175030 (最終更新日 1998-01-06) をもとに作成したものです。

概要

Win32 プログラミングで共通する問題の一つに、すべての "アプリケーション" を列挙することがあります。Windows NT 4.0 のタスク マネージャーがそのよい例です。Windows NT 4.0 のタスク マネージャは、2 種類の方法で "アプリケーション" をリストします。タスク マネージャの最初のタブでは、デスクトップ上にあるすべての "アプリケーション ウインドウ" をリストします。タスク マネージャの 2 つ目のタブでは、システム中のすべての "プロセス" をリストします。この資料では、この 2 種類のタスクを Windows 95 と Windows NT の両方で行う方法について詳しく説明します。

詳細

トップレベル ウインドウの列挙

プロセスの列挙と、デスクトップ上のトップレベル ウインドウの列挙を比較した場合、トップレベル ウインドウを列挙する方が比較的簡単です。Windows NT および Windows 95 プラットフォームでトップレベル ウインドウを列挙するには、EnumWindows() 関数を使用します。GetWindow() でウインドウのリストを作成しないようにしてください。Z オーダー変更によって混乱を招き、ウインドウを損失する可能性があるためです。

EnumWindows() は、パラメータとしてユーザー定義の LPARAM 値、さらにコールバック関数を示すポインタを取ります。EnumWindows() は、スクリーン上のウインドウ(またはトップレベル ウインドウ) 1 つに対してコールバック関数を 1 回呼び出します。呼び出されたコールバック関数は、このウインドウ ハンドルに対してリストに追加するなどの何らかの処理を行います。この方法は、Windows の Z オーダーなどによる変更で混乱を招くことのないように保証されています。ウインドウ ハンドルを取得すると、GetWindowText() を呼び出せば、そのタイトルを取得することができます。

プロセスの列挙

システム中のプロセスのリスト作成は、ウインドウの列挙に比べると多少複雑です。これは、システム中のプロセスのリスト作成を行う API 関数が Windows 95 と Windows NT では根本的に異なっているためです。Windows 95 では、ToolHelp32 という API グループの関数を使用しなければいけません。Windows NT では、PSAPI.DLL の関数を使用します。この DLL は Platform SDK で入手することができます。この資料では、Windows 95 および Windows NT の両方の場合について説明します。また、Windows NT と Windows 95 の両方で動作する "EnumProcs()" という ラッパー関数のサンプルも紹介します。

Windows 95 および ToolHelp32:

最初は、Windows 95 で ToolHelp32 を使う方法から見ていきましょう。KERNEL32.DLL に含まれている ToolHelp32 関数は、Windows 95 でのみ使用できる標準 API 関数群です。ToolHelp32 ではシステム中のプロセスやスレッドを列挙するための関数だけでなく、メモリやモジュール情報を取得するための様々な関数を提供していますが、プロセスを列挙するのに必要な関数は、次の 3 つの関数だけです。

   CreateToolhelp32Snapshot(), Process32First(), and Process32Next().

ToolHelp32 関数を使う最初のステップは、システム中の情報の "スナップショット" をとることです。これには CreateToolhelp32Snapshot() 関数を使用します。この関数を使うと、スナップショットに格納する情報のタイプを指定することができます。プロセス情報も必要なときは、TH32CS_SNAPPROCESS フラグを指定するようにしてください。この関数は HANDLE を返します。このハンドルを使い終わった後は、CloseHandle() に忘れずに呼び出すようにしてください。

次は、スナップショットからプロセスのリストを取得します。まず Process32First を 1 回呼び出し、続いて Process32Next を繰り返し呼び出します。Process32Next はスナップショット中のプロセス リストすべてに対して繰り返し呼び出します。Process32Next が FALSE を返すまで続けます。これらの関数は、どちらもパラメータとしてスナップショットを示すハンドルをとり、さらに PROCESSENTRY32 構造体を示すポインタもとります。

Process32First または Process32Next 呼び出しの後、PROCESSENTRY32 構造体にはシステム中の 1 つのプロセスに関する有益な情報が格納されます。プロセス ID は、この構造体の th32ProcessID メンバにあります。このプロセス ID を OpenProcess() API に渡すと、プロセスを示すハンドルを取得することができます。プロセスの実行可能ファイルとパスは、同じ構造体の szExeFile メンバに格納されています。その他の有益な情報も、この構造体に格納されています。

  注意: Process32First() を呼び出す前に、dwSize メンバに sizeof(PROCESSENTRY32)
       をセットするのを忘れないで下さい。

Windows NT および PSAPI.DLL:

Windows NT でプロセスのリストを作成する場合は、PSAPI.DLL で提供する関数を使用します。PSAPI.DLL ファイルは Platform SDK で配布されます。Platform SDK は、http://www.microsoft.com/msdn/sdk より入手することができます。その他に必要な PSAPI.H および PSAPI.LIB も Platform SDK に含まれています。

PSAPI.DLL 中の関数を使用するには、PSAPI.LIB ファイルをプロジェクトに追加し、PSAPI.DLL 関数を呼び出すすべてのモジュールに PSAPI.H ファイルをインクルードします。PSAPI.DLL を使う実行可能ファイルでは、PSAPI.DLL を忘れずに配布するようにしてください。PSAPI.DLL は現在はオペレーティング システムでは配布していません。

ToolHelp32 関数同様、PSAPI.DLL にも便利な関数がいろいろと含まれています。ただし、今回はプロセス列挙に関連する次の関数のみを紹介します。

   EnumProcesses(), EnumProcessModules(), GetModuleFileNameEx(),
   GetModuleBaseName().

EnumProcesses() は、システム中のプロセス リストを作成するときに使用する最初の関数です。この関数の宣言は次のようになっています。

   BOOL EnumProcesses( DWORD *lpidProcess, DWORD cb, DWORD *cbNeeded );

EnumProcesses() は DWORD 配列( lpidProcess )と 配列のサイズ( cb )を示すポインタおよび DWORD を示すポインタをとり、返されるデータ (cbNeeded) の長さを返します。DWORD 配列は、システム中のプロセスのプロセス ID を格納します。この DWORD パラメータ( cbNeeded )を示すポインタは、使用されている配列のサイズを返します。次の計算処理では、いくつのプロセス ID が返されたかを計算します。

    nReturned = cbNeeded / sizeof(DWORD)

1 つ注意しなければいけないことがあります。ドキュメントでは、このとき返される DWORD を "cbNeeded" と呼んでいますが、実際には配列に渡された値のサイズを見積もる方法は存在していません。EnumProcesses() は、cb パラメータに渡した配列値のサイズを超える値は、cbNeeded には返しません。そのため EnumProcesses() を確実に成功させる唯一の方法として、cbNeeded = cb で返ると、より大きい配列を確保し、cbNeeded < cb となるように何度も同じ処理を繰り返します。

これでシステム中の各プロセス ID に対して配列が作成されました。目的がプロセスの名前を取得することであれば、まずここでハンドルを取得します。プロセス ID からハンドルを取得するときは、OpenProcess() を使用します。

ハンドルを取得したら、プロセスの "最初" のモジュールを取得する必要があります。あるプロセスの最初のモジュールを取得するには、パラメータを次のように指定して EnumProcessModules() を呼び出します。

   EnumProcessModules( hProcess, &hModule, sizeof(hModule), &cbReturned );

この呼び出しの結果、プロセスの最初のモジュールを示すハンドルが hModule 変数に格納されます。プロセスには名前がありませんが、プロセス中の最初のモジュールはそのプロセスの実行可能モジュールとなることができるということを覚えておいてください。
これで、プロセスの実行可能モジュールのパス名、モジュール名を取得するための準備が整いました。これには、hModule を使って GetModuleFileNameEx()、GetModuleBaseName() を呼び出します。どちらの関数も、プロセスを示すハンドル、モジュールを示すハンドル、さらに名前、バッファのサイズを返すバッファ ポインタをとります。

この処理を EnumProcesses() が返す各プロセス ID すべてに対して行います。その結果、Windows NT 上のプロセスのリストが完成します。

16 ビット プロセス:

Windows 95 の 16 ビット アプリケーションは、ToolHelp32 に関する限りは 32 ビット アプリケーションとほぼ同等です。16 ビット アプリケーションにも、Win32 アプリケーション同様、プロセス ID があります。しかし Windows NT の場合は、状況は異なります。

Windows NT 上で実行される 16 ビット アプリケーションは、いわゆる仮想DOS マシン( VDM )で動作します。EnumProcesses はシステム中の 16 ビット アプリケーションを認識することができませんが、16 ビット EXE が実行されている 32 ビット NTVDM プロセスを返します。Windows NT 上で動作する 16 ビット アプリケーションを列挙するには、VDMEnumTaskWOWEx() という関数を使わなければいけません。ソース モジュールに VDMDBG.H をインクルードし、プロジェクトには VDMDBG.LIB ファイルをリンクしてください。これら 2 つのファイルは Platform SDK で出荷されています。

この関数の宣言は次のようになっています。

   INT WINAPI VDMEnumTaskWOWEx( DWORD dwProcessId, TASKENUMPROCEX fp,
                                LPARAM lparam );

dwProcessId には、列挙したい 16 ビット タスクを含む NTVDM プロセスの ID が入ります。fp パラメータは、コールバック関数 "enum" を示すポインタです。また lparam パラメータはユーザー定義の lparam で、enum 関数へ渡されます。

"enum" 関数は、次のように定義してください。

   BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16, PSZ
                       pszModName, PSZ pszFileName, LPARAM lpUserDefined );

この関数は、VDMEnumTaskWOWEx() へ渡される NTVDM プロセスで動作する1つの 16 ビットタスクに対して1回呼ばれます。列挙を継続したい場合は FALSE を返し、列挙を終了したい場合は TRUE を返します。
注意: これは EnumWindows() とは逆なので注意してください。

サンプル コード

以下のサンプル コードは PSAPI.DLL と ToolHelp32 を "EnumProcs()" という 1 つの関数にカプセル化したものです。この関数は EnumWindows() と同様の働きをします。つまり関数へのポインタを使い、システム中の各プロセス毎に関数を繰り返し呼び出します。この関数の宣言は次のように行います。

   BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam );

この関数を使う場合は、コールバック関数を次のように宣言してください。

   BOOL CALLBACK Proc( DWORD dw, WORD w16, LPCSTR lpstr, LPARAM lParam );

dw パラメータには ID が入り、w16 には 16 ビット タスク番号または 32 ビット プロセスの場合は 0 が入ります。( Windows 95 では常にゼロが入ります。) lpstr パラメータにはファイル名を示すポインタが入り、lParam はユーザー定義の lParam で EnumProcs() に渡されます。

EnumProcs() 関数は、明示的にリンクすることで ToolHelp32 および PSAPI.DLL 関数を使用します。通常の暗黙のリンクではないのでご注意ください。これは、EnumProcs() 関数を含むコードが、Windows NT と Windows 95 でバイナリ互換できるようにするためです。( ToolHelp32 関数を暗黙のリンクで使用すると、Windows NT では EXE のロードに失敗し実行することができません。)

   /*********************
   EnumProc.h
   *********************/
   #include <windows.h>

   typedef BOOL (CALLBACK *PROCENUMPROC)( DWORD, WORD, LPSTR,
      LPARAM ) ;

   BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam ) ;

   /*********************
   EnumProc.c (or .cpp)
   *********************/
   #include "EnumProc.h"
   #include <tlhelp32.h>
   #include <vdmdbg.h>

   typedef struct
   {
      DWORD          dwPID ;
      PROCENUMPROC   lpProc ;
      DWORD          lParam ;
      BOOL           bEnd ;
   } EnumInfoStruct ;

   BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
      PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) ;

   // EnumProcs 関数はコールバック関数を示すポインタをとります。
   // このコールバック関数は、プロセス EXE のファイル名とプロセス ID を提供する
   // システム中の、プロセスごとに1回呼ばれます。
   // コールバック関数の定義:
   // BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam ) ;
   //
   // lpProc - コールバック ルーチンのアドレス。
   //
   // lParam - コールバック ルーチンに渡されるユーザー定義の LPARAM 値。
   //
   BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam )
   {
      OSVERSIONINFO  osver ;
      HINSTANCE      hInstLib ;
      HINSTANCE      hInstLib2 ;
      HANDLE         hSnapShot ;
      PROCESSENTRY32 procentry ;
      BOOL           bFlag ;
      LPDWORD        lpdwPIDs ;
      DWORD          dwSize, dwSize2, dwIndex ;
      HMODULE        hMod ;
      HANDLE         hProcess ;
      char           szFileName[ MAX_PATH ] ;
      EnumInfoStruct sInfo ;

      // ToolHelp 関数のポインタ。
      HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
      BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
      BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;

      // PSAPI 関数のポインタ。
      BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
      BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
         DWORD, LPDWORD );
      DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE,
         LPTSTR, DWORD );

      // VDMDBG 関数のポインタ。
      INT (WINAPI *lpfVDMEnumTaskWOWEx)( DWORD,
         TASKENUMPROCEX  fp, LPARAM );

      // 実行されているのが Windows 95 か Windows NT かを確認します。
      osver.dwOSVersionInfoSize = sizeof( osver ) ;
      if( !GetVersionEx( &osver ) )
      {
         return FALSE ;
      }

      // Windows NT の場合:
      if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT )
      {

         // ライブラリをロードし、プロシージャを明示的に取得します。
         // これは、PSAPI.DLL への参照を解決できないという理由で
         // Windows 95 でのロードが失敗しないようにするための配慮です。
         hInstLib = LoadLibraryA( "PSAPI.DLL" ) ;
         if( hInstLib == NULL )
            return FALSE ;

         hInstLib2 = LoadLibraryA( "VDMDBG.DLL" ) ;
         if( hInstLib2 == NULL )
            return FALSE ;

         // プロシージャのアドレスを取得します。
         lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
            GetProcAddress( hInstLib, "EnumProcesses" ) ;
         lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
            DWORD, LPDWORD)) GetProcAddress( hInstLib,
            "EnumProcessModules" ) ;
         lpfGetModuleFileNameEx =(DWORD (WINAPI *)(HANDLE, HMODULE,
            LPTSTR, DWORD )) GetProcAddress( hInstLib,
            "GetModuleFileNameExA" ) ;
         lpfVDMEnumTaskWOWEx =(INT(WINAPI *)( DWORD, TASKENUMPROCEX,
            LPARAM))GetProcAddress( hInstLib2, "VDMEnumTaskWOWEx" );
         if( lpfEnumProcesses == NULL ||
            lpfEnumProcessModules == NULL ||
            lpfGetModuleFileNameEx == NULL ||
            lpfVDMEnumTaskWOWEx == NULL)
            {
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }

         // PSAPI 関数の EnumProcesses を呼び出して、現在システム中にある
         // すべての ProcID を取得します。
         // 注意: ドキュメントには、EnumProcesses の第三パラメータは 
         // cbNeeded であると書かれていますが、これはこの関数を 1度呼び出すと
         // 確保するバッファのサイズを確認することができ、2度目の呼び出しで
         // バッファにデータを格納することができるということを暗に意味してい
         // ます。
         // この説明はこのケースには当てはまりません。CbNeeded パラメータは、
         // 返された PID の数を返します。そのためバッファ サイズがゼロの
         // 場合は、cbNeeded はゼロを返します。
         // 注意: "HeapAlloc" のループは、システム中のすべての PID に対して
         // 適切なサイズのバッファを確実に割り当てるための対策です。
         dwSize2 = 256 * sizeof( DWORD ) ;
         lpdwPIDs = NULL ;
         do
         {
            if( lpdwPIDs )
            {
               HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
               dwSize2 *= 2 ;
            }
            lpdwPIDs = HeapAlloc( GetProcessHeap(), 0, dwSize2 );
            if( lpdwPIDs == NULL )
            {
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }
            if( !lpfEnumProcesses( lpdwPIDs, dwSize2, &dwSize ) )
            {
               HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }
         }while( dwSize == dwSize2 ) ;

         // 取得した ProcID の数は?
         dwSize /= sizeof( DWORD ) ;

         // 各 ProcID に対してループ。
         for( dwIndex = 0 ; dwIndex < dwSize ; dwIndex++ )
         {
            szFileName[0] = 0 ;
            // プロセスをオープンします。(セキュリティによってシステム中の
            // 各プロセスにアクセスできない可能性があります。)
            hProcess = OpenProcess(
               PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
               FALSE, lpdwPIDs[ dwIndex ] ) ;
            if( hProcess != NULL )
            {
               // ここで EnumProcessModules を呼び出して、プロセス中の最初の
               // モジュールのみを取得します。これは、次にフル パス名を取得する
               // ための .EXE モジュールとなるためとても重要な処理です。
               if( lpfEnumProcessModules( hProcess, &hMod,
                  sizeof( hMod ), &dwSize2 ) )
               {
                  // フル パス名を取得します。
                  if( !lpfGetModuleFileNameEx( hProcess, hMod,
                     szFileName, sizeof( szFileName ) ) )
                  {
                     szFileName[0] = 0 ;
                    }
               }
               CloseHandle( hProcess ) ;
            }
            // OpenProcess の成功の有無に関係なく、ProcID を使って enum 関数を
            // 呼ぶことができます。
            if(!lpProc( lpdwPIDs[dwIndex], 0, szFileName, lParam))
               break ;

            // NTVDM はありましたか?
            if( _stricmp( szFileName+(strlen(szFileName)-9),
               "NTVDM.EXE")==0)
            {
               // 16 ビット enum proc の情報を格納します。
               sInfo.dwPID = lpdwPIDs[dwIndex] ;
               sInfo.lpProc = lpProc ;
               sInfo.lParam = lParam ;
               sInfo.bEnd = FALSE ;
               // 16 ビット スタッフを列挙します。
               lpfVDMEnumTaskWOWEx( lpdwPIDs[dwIndex],
                  (TASKENUMPROCEX) Enum16,
                  (LPARAM) &sInfo);

               // メイン enum 関数は終了していますか?
               if(sInfo.bEnd)
                  break ;
            }
         }

         HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
         FreeLibrary( hInstLib2 ) ;

      // Windows 95 の場合:
      }else if( osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
      {

         hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
         if( hInstLib == NULL )
            return FALSE ;

         // プロシージャのアドレスを取得します。
         // Kernel32 のこれらの関数を明示的にリンクしています。そうしないと
         // このコードを使用するモジュールは、 Kernel32 に Toolhelp32 を
         // 持たない Windows NT 上ではロードに失敗するためです。
         lpfCreateToolhelp32Snapshot=
            (HANDLE(WINAPI *)(DWORD,DWORD))
            GetProcAddress( hInstLib,
            "CreateToolhelp32Snapshot" ) ;
         lpfProcess32First=
            (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
            GetProcAddress( hInstLib, "Process32First" ) ;
         lpfProcess32Next=
            (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
            GetProcAddress( hInstLib, "Process32Next" ) ;
         if( lpfProcess32Next == NULL ||
            lpfProcess32First == NULL ||
            lpfCreateToolhelp32Snapshot == NULL )
         {
            FreeLibrary( hInstLib ) ;
            return FALSE ;
         }

         // システム プロセスの Toolhelp スナップショットを示すハンドルを
         // 取得します。
         hSnapShot = lpfCreateToolhelp32Snapshot(
            TH32CS_SNAPPROCESS, 0 ) ;
         if( hSnapShot == INVALID_HANDLE_VALUE )
         {
            FreeLibrary( hInstLib ) ;
            return FALSE ;
         }

         // 最初のプロセスの情報を取得します。
         procentry.dwSize = sizeof(PROCESSENTRY32) ;
         bFlag = lpfProcess32First( hSnapShot, &procentry ) ;

         // プロセスがある間、ループを繰り返します。
         while( bFlag )
         {
            // ファイル名と ProcID を使って enum 関数を呼び出します。
            if(lpProc( procentry.th32ProcessID, 0,
               procentry.szExeFile, lParam ))
            {
               procentry.dwSize = sizeof(PROCESSENTRY32) ;
               bFlag = lpfProcess32Next( hSnapShot, &procentry );
            }else
               bFlag = FALSE ;
         }

      }else
         return FALSE ;

      // ライブラリを開放します。
      FreeLibrary( hInstLib ) ;

      return TRUE ;
   }

   BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
      PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined )
   {
      BOOL bRet ;

      EnumInfoStruct *psInfo = (EnumInfoStruct *)lpUserDefined ;

      bRet = psInfo->lpProc( psInfo->dwPID, hTask16, pszFileName,
         psInfo->lParam ) ;

      if(!bRet)
      {
         psInfo->bEnd = TRUE ;
      }

      return !bRet;
   }




この情報は、お客様の疑問・問題解決の
お役に立ちましたか?

 はい。問題・疑問が解決しました。
 解決しなかったが参考になりました。
 いいえ。役に立ちませんでした。


Keywords: BseDebug BseMisc BseProcThrd
Version: 95 3.5 4.0
Platform: WINDOWS95 WINDOWSNT
Issue type: KBHOWTO

    Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。
    なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合があります。マイクロソフトの商標および製品名については こちら をご参照ください。

Last Updated: 01/02/28
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.