PSAPI とは,WindowsNT4.0 にて,Process/Thread を列挙したり EXE 名を取得したりできる DLLである.(詳しくは MSJ No.46 Under the Hood)
NT 系でしか使用できず,OS には含まれていない(再配布が必要)
Windows95 系では ToolHelp32 を使用する.(MSJ No.40 Under the Hood)
#include <psapi.h>
#include <tlhelp32.h>
//
// ウィンドウハンドルから EXE 名取得
//
// HWND hWnd : ウィンドウハンドル
// LPTSTR lpszFileName : フルパスバッファ
// DWORD nSize : バッファ最大長
//
// return : BOOL : TRUE : 成功
// FALSE : 失敗
//
BOOL GetFNameFromHandled(HWND hWnd, LPTSTR lpszFileName, DWORD nSize)
{
BOOL bResult = FALSE;
DWORD dwProcessId; // プロセス ID
GetWindowThreadProcessId(hWnd , &dwProcessId);
// OS 判断
OSVERSIONINFO osverinfo;
osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if( !GetVersionEx(&osverinfo) ) {
return FALSE;
}
// Windows NT/2000
if( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) {
// PSAPI 関数のポインタ
BOOL (WINAPI *lpfEnumProcessModules)
(HANDLE, HMODULE*, DWORD, LPDWORD);
DWORD (WINAPI *lpfGetModuleFileNameEx)
(HANDLE, HMODULE, LPTSTR, DWORD);
// PSAPI.DLL ライブラリをロード
HINSTANCE hInstLib = LoadLibrary("PSAPI.DLL");
if( hInstLib == NULL ) {
return FALSE ;
}
// プロシージャのアドレスを取得
lpfEnumProcessModules = (BOOL(WINAPI *)
(HANDLE, HMODULE *, DWORD, LPDWORD))GetProcAddress(
hInstLib, "EnumProcessModules");
lpfGetModuleFileNameEx =(DWORD (WINAPI *)
(HANDLE, HMODULE, LPTSTR, DWORD))GetProcAddress(
hInstLib, "GetModuleFileNameExA");
if( lpfEnumProcessModules && lpfGetModuleFileNameEx ) {
// プロセスのハンドルを取得
HANDLE hProcess;
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, dwProcessId);
if( hProcess ) {
// EXE モジュールのハンドルを取得
HMODULE hModule;
DWORD dwNeed;
if(lpfEnumProcessModules(hProcess, &hModule, sizeof(hModule), &dwNeed) ) {
// モジュールハンドルからフルパス名を取得
if( lpfGetModuleFileNameEx(hProcess, hModule, lpszFileName, nSize) ) {
bResult = TRUE;
}
}
// プロセスオブジェクトのハンドルをクローズ
CloseHandle( hProcess ) ;
}
}
// PSAPI.DLL ライブラリを開放
FreeLibrary( hInstLib ) ;
}
// Windows 9x
else if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) {
// ToolHelp 関数ポインタ
HANDLE (WINAPI *lpfCreateSnapshot)(DWORD, DWORD);
BOOL (WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32);
BOOL (WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32);
// プロシージャのアドレスを取得
lpfCreateSnapshot =
(HANDLE(WINAPI*)(DWORD,DWORD))GetProcAddress(
GetModuleHandle("kernel32.dll"),
"CreateToolhelp32Snapshot" );
lpfProcess32First=
(BOOL(WINAPI*)(HANDLE,LPPROCESSENTRY32))GetProcAddress(
GetModuleHandle("kernel32.dll"),
"Process32First" );
lpfProcess32Next=
(BOOL(WINAPI*)(HANDLE,LPPROCESSENTRY32))GetProcAddress(
GetModuleHandle("kernel32.dll"),
"Process32Next" );
if( !lpfCreateSnapshot
|| !lpfProcess32First
|| !lpfProcess32Next) {
return FALSE;
}
// システム プロセスの Toolhelp スナップショットを作成
HANDLE hSnapshot;
hSnapshot = lpfCreateSnapshot(TH32CS_SNAPPROCESS , 0);
if(hSnapshot != (HANDLE)-1) {
// 最初のプロセスに関する情報を取得
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
if( lpfProcess32First(hSnapshot, &pe) ) {
do {
// 同じプロセスID であれば、ファイル名を取得
if(pe.th32ProcessID == dwProcessId) {
lstrcpy(lpszFileName, pe.szExeFile);
bResult = TRUE;
break;
}
} while( lpfProcess32Next(hSnapshot, &pe) );
}
// スナップショットを破棄
CloseHandle(hSnapshot);
}
} else {
return FALSE;
}
return bResult;
}
参照
アプリケーションの列挙