指定したexeが起動しているかの判別方法

解決


tororo  2004-05-10 06:12:02  No: 8841

指定したexeが起動しているかどうか調べたいのですが、
どのようにしたらいいのか分かりません。

どなたか教えてください、お願いします。


jok  2004-05-10 09:04:06  No: 8842

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;


tororo  2004-05-10 21:31:03  No: 8843

Win95,98,Me でするにはどうすればいいでしょうか?


jok  2004-05-10 22:16:02  No: 8844

> 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;


にゃ〜  2004-05-11 10:13:58  No: 8845

もっと簡単に、これではダメかにゃ〜?

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  2004-05-11 11:54:32  No: 8846

なるほど。起動されているときは書き込みでオープンできないことを
利用しているわけですね。これは簡単ですね。すばらしい。

わたしは、プロセスの一覧から情報を取得することばかりを考えていました。
盲点を衝かれたようで、発想に驚きました。


tororo  2004-05-12 01:07:58  No: 8847

にゃ〜さんの方法で試したところ判別することができました。
ソース付きで解説してくださったjokさん、にゃ〜さん
どうもありがとございました。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加