确定进程是否处于活动状态

时间:2013-06-01 18:19:04

标签: delphi

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,Tlhelp32, StdCtrls;

  function processExists(exeFileName: string): Boolean; 
var
  ContinueLoop: BOOL; 
  FSnapshotHandle: THandle; 
  FProcessEntry32: TProcessEntry32;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32); 
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); 
  Result := False;
  while Integer(ContinueLoop) <> 0 do 
  begin 
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = 
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = 
      UpperCase(ExeFileName))) then
    begin 
      Result := True; 
    end; 
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); 
  end;
  CloseHandle(FSnapshotHandle); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
  if processExists('notepad.exe') then 
    ShowMessage('process is running')
  else 
    ShowMessage('process not running');
end;

enprocedure TForm1.Button1Click(Sender: TObject);
begin

end;

这是我确切的代码即时出错,这是delphi技巧的例子。现在我只是试图填写我的编辑,以便stackoverflow让我发布我的编辑,我显然主要是代码,所以我需要礼貌地添加更多的细节

3 个答案:

答案 0 :(得分:5)

您的问题中的代码失败了,因为您已设法将函数processExists的内容复制到FormCreate方法而不是实际函数本身。

FormCreate中移除代码并在实现部分中实现函数processExists

function processExists(exeFileName : string) : Boolean;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeFileName))) then
    begin
      Result := True;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);  
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if processExists('notepad.exe') then
    ShowMessage('process is running')
  else
    ShowMessage('process not running');
end;

答案 1 :(得分:3)

代码似乎位于错误的位置。我们无法看到您ProcessExists的实现,但代码应该存在。

但我想专注于包含多个错误的问题中的代码。这是我写它的方式:

function ProcessExists(const ExeFileName: string): Boolean;
var
  SnapshotHandle: THandle;
  ProcessEntry32: TProcessEntry32;
  Continue: BOOL;
begin
  Result := False;
  SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  Win32Check(SnapshotHandle<>INVALID_HANDLE_VALUE);
  try
    ProcessEntry32.dwSize := SizeOf(ProcessEntry32);
    Continue := Process32First(SnapshotHandle, ProcessEntry32);
    while Continue do
    begin
      if SameText(ProcessEntry32.szExeFile, ExeFileName) then
      begin
        Result := True;
        exit;
      end;
      Continue := Process32Next(SnapshotHandle, ProcessEntry32);
    end;
  finally
    CloseHandle(SnapshotHandle);
  end;
end;

我已解决的问题:

  1. 此处不要使用全局变量。这里的变量都可以是,也应该是局部变量。支持所有其他变量的局部变量,并尽可能使用它们。
  2. 不要将BOOL转换为整数并与0进行比较。BOOL是逻辑的,因此可以直接在逻辑上下文中使用。
  3. 使用SameText而非UpperCase混乱。
  4. 不要两次执行相同的文本比较。一次就够了。
  5. 找到匹配项时突破循环。
  6. 使用try / finally防范导致资源泄漏的异常。

答案 2 :(得分:1)

链接页面中显示的代码使用的是Windows中的ToolHelp API。您应该查看链接页面。

当您使用该API时,您将创建操作系统当前进程列表的快照,并使用Process32First和Process32Next遍历该列表以检测该进程。

建议:MadCollection的MadKernel部分(MadExcept和MadCodeHook是付费部分)围绕这些函数做了一个非常好用且有用的包装器。这些调用使我的50行功能将消息发送到父应用程序到10行一。

PS:除了使用他们的libs之外,我与madshi.net没有关系; - )