指定したアプリケーションが起動中か調べる |
通常、アプリケーションが起動中かどうかはCreateProcess()で起動し
プロセスハンドルを保持して起動中か判断しますが
CreateProcess()で起動しないとプロセスハンドルを得ることが出来ません。
そこでアプリケーションのパスからそのアプリケーションが起動中か
調べる方法を紹介します。
まずは以下の関数を作成します。
#include <tlhelp32.h> // 追加する #pragma comment(lib, "th32.lib") // 追加する BOOL fCheckExistProcess95(LPCTSTR pszExeName) { PROCESSENTRY32 pe32 = {0}; BOOL fOK; BOOL fFind = FALSE; HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(!hSnapshot) return FALSE; pe32.dwSize = sizeof(pe32); if(!::Process32First(hSnapshot, &pe32)) return FALSE; do{ if(lstrcmpi(pe32.szExeFile, pszExeName) == 0) { fFind = TRUE; continue; } fOK = ::Process32Next(hSnapshot, &pe32); } while(fOK && (!fFind)); ::CloseHandle(hSnapshot); return fFind; } |
ハイ、長いですね。
実は私はこれが何をやっているかは分かりませんので詳しい説明は出来ません。(^^;
某掲示板に有ったソースをちょっと見やすく書き直しただけです。
この関数は引数に実行ファイルのパスを渡すと戻り値で
そのアプリケーションが起動中ならTRUEが戻ってきます。
しかしこの関数は名前からみても分かるようにWin95系でしか使えません。
WinNT系では以下の方法で判断できます。
#include <winperf.h> // 追加する BOOL fCheckExistProcessNT(LPCTSTR pszExeName) { const LPTSTR c_szRegKeyPerf = _T("software\\microsoft\\windows nt\\currentversion\\perflib"); const LPTSTR c_szRegSubkeyCounters = _T("Counters"); // COUNTERサブキー const LPTSTR c_szProcessCounter = _T("process"); const LPTSTR c_szProcessIdCounter = _T("id process"); const DWORD c_dwInitialSize = 51200L; const DWORD c_szExtendSize = 25600L; DWORD dwNumTasks; // 最大タスク数 HKEY hKeyNames; CString cstrKey, cstrSubKey; LANGID lid; LPBYTE p; LPBYTE p2; DWORD dwProcessIdTitle; DWORD dwSize,dwType; PPERF_DATA_BLOCK pPerf; PPERF_OBJECT_TYPE pObj; PPERF_INSTANCE_DEFINITION pInst; PPERF_COUNTER_BLOCK pCounter; PPERF_COUNTER_DEFINITION pCounterDef; DWORD i; DWORD dwProcessIdCounter; LPBYTE buf = NULL; CString cstrProcessName; DWORD dwValueSize; long lRet; int iRet; BOOL fOK = FALSE; // 日本語 lid = MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL); cstrKey.Format(_T("%s\\%03x"), c_szRegKeyPerf, lid); if(ERROR_SUCCESS != ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, cstrKey, 0, KEY_READ, &hKeyNames)) goto exit; // get the buffer size for the counter names if(ERROR_SUCCESS != ::RegQueryValueEx(hKeyNames, c_szRegSubkeyCounters, NULL, &dwType, NULL, &dwSize)) goto exit; // allocate the counter names buffer buf = new BYTE [dwSize]; if(buf == NULL) goto exit; memset(buf, 0, dwSize); // read the counter names from the registry if(ERROR_SUCCESS != ::RegQueryValueEx(hKeyNames, c_szRegSubkeyCounters, NULL, &dwType, buf, &dwSize)) goto exit; p = buf; while(*p){ if(p > buf) for(p2 = p - 2; isdigit(*p2); p2--); if(::lstrcmpi((LPSTR)p, c_szProcessCounter) == 0 ) { // look backwards for the counter number for(p2 = p - 2; isdigit(*p2); p2--); cstrSubKey = p2 + 1; } else if(::lstrcmpi((LPSTR)p, c_szProcessIdCounter) == 0) { // look backwards for the counter number for(p2 = p - 2; isdigit(*p2); p2--); dwProcessIdTitle = atol((LPSTR)(p2+1)); } // next string p += (lstrlen((LPSTR)p) + 1); } // free the counter names buffer if(buf) delete [] buf; // allocate the initial buffer for the performance data dwSize = c_dwInitialSize; buf = new BYTE[dwSize]; if(buf == NULL) goto exit; memset(buf, 0, dwSize); while(TRUE) { dwValueSize = dwSize; lRet = ::RegQueryValueEx(HKEY_PERFORMANCE_DATA, cstrSubKey.GetBuffer(128), NULL, NULL, buf, &dwValueSize); cstrSubKey.ReleaseBuffer(); pPerf = (PPERF_DATA_BLOCK) buf; // perfデータプロックのシグニチャチェック if((lRet == ERROR_SUCCESS) && (dwSize > 0) && (pPerf)->Signature[0] == (WCHAR)'P' && (pPerf)->Signature[1] == (WCHAR)'E' && (pPerf)->Signature[2] == (WCHAR)'R' && (pPerf)->Signature[3] == (WCHAR)'F') break; // 領域の拡大 if(lRet == ERROR_MORE_DATA) { dwSize += c_szExtendSize; delete [] buf; buf = new BYTE[dwSize]; if(buf == NULL) goto exit; memset(buf, 0, dwSize); } else goto exit; } // perf_object_type ポインタセット pObj = (PPERF_OBJECT_TYPE)((DWORD)pPerf + pPerf->HeaderLength); // loop thru the performance counter definition records looking // for the process id counter and then save its offset pCounterDef = (PPERF_COUNTER_DEFINITION)((DWORD)pObj + pObj->HeaderLength); for(i = 0; i < (DWORD)pObj->NumCounters; i++) { if(pCounterDef->CounterNameTitleIndex == dwProcessIdTitle) { dwProcessIdCounter = pCounterDef->CounterOffset; break; } pCounterDef++; } dwNumTasks = (DWORD)pObj->NumInstances; pInst = (PPERF_INSTANCE_DEFINITION)((DWORD)pObj + pObj->DefinitionLength); // パフォーマンスインスタンスデータよりプロセス名サーチ for(i = 0 ; i < dwNumTasks ; i++) { // プロセス名へのポインタ p = (LPBYTE)((DWORD)pInst + pInst->NameOffset); cstrProcessName.Empty(); if(!::IsBadStringPtr((LPSTR)p, MAX_PATH)) { // Unicode から asciiに変換 iRet = ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)p, -1, cstrProcessName.GetBuffer(MAX_PATH), MAX_PATH, NULL, NULL); cstrProcessName.ReleaseBuffer(); cstrProcessName += _T(".exe"); if(iRet > 0) { CString cstrName; LPSTR pszFilePart; ::GetFullPathName(pszExeName, MAX_PATH, cstrName.GetBuffer(MAX_PATH), &pszFilePart); cstrName.ReleaseBuffer(); cstrName = pszFilePart; if(0 == cstrProcessName.CompareNoCase(cstrName)) { fOK = TRUE; break; } } } pCounter = (PPERF_COUNTER_BLOCK)((DWORD)pInst + pInst->ByteLength); // next process pInst = (PPERF_INSTANCE_DEFINITION)((DWORD)pCounter + pCounter->ByteLength); } exit: ::RegCloseKey(hKeyNames); ::RegCloseKey(HKEY_PERFORMANCE_DATA); if(buf) delete [] buf; return fOK; } |
ハイ、ものすごく長いですね。(笑)
当然なにをやってるかなんてサッパリです。
ただこの関数も引数にアプリケーションのパスを渡すと
戻り値で起動中ならTRUEを返してきます。
さてこれをWin95系とNT系に対応しなければなりませんが
それには使用しているOSが何かを調べる必要があります。
GetVersionEx()というAPIでOSのバージョンを調べられるのでそれを利用します。
// 95系かNT系かを調べる。 OSVERSIONINFO osInfo; osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osInfo); BOOL res; char lpCommandLine[] = _T("アプリケーションのパス"); if(osInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) res = fCheckExistProcess95(lpCommandLine); else res = fCheckExistProcessNT(lpCommandLine); // 状態の表示 if(res) AfxMessageBox(_T("起動しています。")); else AfxMessageBox(_T("起動していません。")); |
と、こんな感じで判断してそれに合った関数を呼び出せばOKでしょう。
GetVersionEx()の引数のOSVERSIONINFO構造体にOSの情報が格納されます。
この構造体のdwPlatformIdがVER_PLATFORM_WIN32_WINDOWSならWin95系で
VER_PLATFORM_WIN32_NTならWinNT系です。
それからGetVersionEx()を呼び出す前にOSVERSIONINFO構造体の
dwOSVersionInfoSizeメンバをsizeof(OSVERSIONINFO)で初期化する必要があります。
以上で終わりですが起動チェックの関数はマジで分かりません。
もし不具合が有っても直す事は不可能でしょう。(^^;
< 戻る << HOME | ©1999-2001 by Akky, All right reserved. |