指定したexeが起動しているかどうか調べたいのですが、
どのようにしたらいいのか分かりません。
どなたか教えてください、お願いします。
WindowsNT4,2000,XP では以下のようにして判別できます。
Win95,98,Me では適用できません。
uses
PsAPI;
function GetAllProcessModuleName(SL:TStringList):Boolean;
var
ProcessIDs:array[0..200] of DWORD;
Num4,NumProcess:DWORD;
i:integer;
hProcess,hModule:THandle;
lpBaseName:PChar;
s:string;
begin
result := false;
if not EnumProcesses(@ProcessIDs,SizeOf(ProcessIDs),Num4) then begin
ShowMessage('EnumProcesses Failed!');
Exit;
end;
NumProcess := Num4 div SizeOf(DWORD);
GetMem(lpBaseName,101);
for i := 0 to NumProcess -1 do begin
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
false, ProcessIDs[i]);
EnumProcessModules(hProcess,@hModule,SizeOf(hModule),Num4);
Num4 := GetModuleBaseName(hProcess,hModule,lpBaseName,100);
SetString(s,lpBaseName,Num4);
SL.Add(s);
CloseHandle(hProcess);
end;
FreeMem(lpBaseName);
result := true;
end;
function IsExefileRunning(ExeFilename:string):Boolean;
var
SL:TStringList;
i:integer;
begin
result := false;
SL := TStringList.Create;
try
if GetAllProcessModuleName(SL) then begin
for i := 0 to SL.Count-1 do SL[i] := UpperCase(SL[i]);
result := SL.IndexOf(UpperCase(ExeFilename)) <> -1;
end;
finally
SL.Free;
end;
end;
// メモ帳が起動されているかどうかを判断する
procedure TForm1.Button1Click(Sender: TObject);
begin
if IsExefileRunning('Notepad.exe') then
ShowMessage('Running')
else
ShowMessage('not Running');
end;
Win95,98,Me でするにはどうすればいいでしょうか?
> Win95,98,Me でするにはどうすればいいでしょうか?
uses
TLHelp32;
function GetProcessModule(dwPID:DWORD;dwModuleID:DWORD;
var Me32:TModuleEntry32):Boolean;
var
hModuleSnap:THandle;
cMe32:TModuleEntry32;
begin
result := false;
hModuleSnap := CreateToolHelp32Snapshot(TH32CS_SNAPMODULE,dwPID);
if hModuleSnap = INVALID_HANDLE_VALUE then exit;
cMe32.dwSize := SizeOf(TModuleEntry32);
if Module32First(hModuleSnap,cMe32) then begin
repeat
if cMe32.th32ModuleID = dwModuleID then begin
Me32 := cMe32;
result := true;
end;
until (result or not Module32Next(hModuleSnap,cMe32));
end else
result := false;
CloseHandle(hModuleSnap);
end;
function GetProcessList(SL:TStrings):Boolean;
var
hProcessSnap:THandle;
Pe32:TProcessEntry32;
bGotModule:Boolean;
Me32:TModuleEntry32;
begin
hProcessSnap := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS,0);
if hProcessSnap = INVALID_HANDLE_VALUE then begin
result := false;
exit;
end;
Pe32.dwSize := SizeOf(TProcessEntry32);
if Process32First(hProcessSnap,Pe32) then begin
repeat
bGotModule := GetProcessModule(Pe32.th32ProcessID,Pe32.th32ModuleID,Me32);
if bGotModule then
SL.AddObject(Me32.SzExePath,TObject(Pe32.th32ProcessID));
until not Process32Next(hProcessSnap,Pe32);
result := True;
end else
result := false;
CloseHandle(hProcessSnap);
end;
function IsExefileRunning(ExeFilename:string):Boolean;
var
SL:TStringList;
i:integer;
begin
result := false;
SL := TStringList.Create;
try
if GetProcessList(SL) then begin
for i := 0 to SL.Count-1 do SL[i] := UpperCase(ExtractFileName(SL[i]));
result := SL.IndexOf(UpperCase(ExeFilename)) <> -1;
end;
finally
SL.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if IsExefileRunning('Notepad.exe') then
ShowMessage('Running')
else
ShowMessage('not Running');
end;
もっと簡単に、これではダメかにゃ〜?
function IsFileOccupied(FileName: TFileName): Boolean;
var
hFileRes : HFILE;
begin
result := False;
hFileRes := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE,
0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
result := (hFileRes = INVALID_HANDLE_VALUE);
if not result then CloseHandle(hFileRes);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if IsFileOccupied('C:\Windows\Notepad.exe') then begin
ShowMessage('使ってるにゃ〜');
end else begin
ShowMessage('使っていないにゃ〜');
end;
end;
なるほど。起動されているときは書き込みでオープンできないことを
利用しているわけですね。これは簡単ですね。すばらしい。
わたしは、プロセスの一覧から情報を取得することばかりを考えていました。
盲点を衝かれたようで、発想に驚きました。
にゃ〜さんの方法で試したところ判別することができました。
ソース付きで解説してくださったjokさん、にゃ〜さん
どうもありがとございました。
ツイート | ![]() |