- ベストアンサー
他のEXEが起動しているかの確認
お世話になります。 C++.net2003で開発しております。 あるのA.EXEが起動しているかの確認をしたいのですが、 他のユーザがA.EXEを起動しているかはどのように確認できるでしょうか? ※A.EXEに上書きする権限がないので、上書きできることで確認ができない。 ※A.EXEはMUTEXがローカルMUTEXしかもっていない。 以上よろしくお願いします。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
1.プロセスをリストする 2.リストしたプロセスのうち、ファイル名が「A.EXE」になっている物を探す(A.EXEがリネームされている場合はどうしようもない) 3.探したプロセスのメモリの特定部分を検査し、A.EXEかどうか確認する(例えば、コードブロックメモリの先頭にあるバージョン情報や、リソース情報を読み取る) //変数宣言 PROCESSENTRY32 *ProcessList; DWORD ProcessListSize; DWORD ProcessListCount; BOOL (WINAPI *lpfEnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD); DWORD (WINAPI *lpfGetModuleFileNameEx)(HANDLE, HMODULE, LPTSTR, DWORD); HINSTANCE hInstLib; //初期化部分 hInstLib = NULL; if (GetVersion() < 0x80000000) { //WinNT or WinXP hInstLib = LoadLibrary("PSAPI.DLL"); if (hInstLib) { lpfEnumProcessModules = (BOOL (WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress(hInstLib, "EnumProcessModules"); lpfGetModuleFileNameEx = (DWORD (WINAPI *)(HANDLE, HMODULE,LPTSTR, DWORD)) GetProcAddress(hInstLib,"GetModuleFileNameExA"); if (!lpfEnumProcessModules && !lpfGetModuleFileNameEx) { lpfEnumProcessModules = NULL; lpfGetModuleFileNameEx = NULL; FreeLibrary(hInstLib); hInstLib = NULL; } } } //プロセスのリスト関数 DWORD __fastcall GetProcessList(PROCESSENTRY32 *ProcList, DWORD ListSize, LPDWORD Needed) { DWORD Need = 0; DWORD SetCount = 0; HANDLE hSnapshot; HANDLE hProcess; PROCESSENTRY32 procent; HMODULE hMod; DWORD dwSize; CHAR szFileName[MAX_PATH]; hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if (hSnapshot != (HANDLE)-1) { procent.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hSnapshot,&procent)) { do { hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, procent.th32ProcessID); if (hProcess) { if ((ListSize) && (ProcList)) { //WinNT or WinXP if (hInstLib) { if (lpfEnumProcessModules(hProcess, &hMod, sizeof(hMod), &dwSize)) if (lpfGetModuleFileNameEx(hProcess, hMod, szFileName, sizeof(szFileName))) { strncpy(procent.szExeFile,szFileName,MAX_PATH - 1); procent.szExeFile[MAX_PATH - 1] = '\0'; } } *ProcList++ = procent; ListSize--; SetCount++; } Need++; CloseHandle(hProcess); } } while(Process32Next(hSnapshot,&procent) != FALSE); } CloseHandle(hSnapshot); } if (Needed) *Needed = SetCount; return Need; } //関数の呼び出し部分 PROCESSENTRY32 *NewProcessList; i = GetProcessList(ProcessList, ProcessListSize, &ProcessListCount); if (i > ProcessListSize) { NewProcessList = (PROCESSENTRY32 *)realloc(ProcessList,(i + 16) * sizeof(PROCESSENTRY32)); if (!NewProcessList) { ProcessList = NewProcessList; ProcessListSize = i + 16; } GetProcessList(ProcessList, ProcessListSize, &ProcessListCount); } //i番目のプロセスにアタッチする DWORD ProcessId; ProcessId = ProcessList[i]->th32ProcessID; if (ExecProcessHandle) CloseHandle(ExecProcessHandle); ExecProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessId); //アタッチしたプロセスのメモリを1バイト読む unsigned char cbuf[3]; int StartAddress; int err; DWORD Rb; Rb = 0; err = ReadProcessMemory(ExecProcessHandle, (void *)StartAddress, cbuf, 1, &Rb); if (!err) { err = GetLastError(); if ((err != ERROR_PARTIAL_COPY) && (err != ERROR_NOACCESS)) { //該当プロセスが終了してメモリにアクセスできない } }