一个笨办法是EnumProcess:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Panel1: TPanel;
Button2: TButton;
ListBox2: TListBox;
Splitter1: TSplitter;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses psapi;
{$R *.DFM}
procedure TForm1.Button2Click(Sender: TObject);
type
integer = DWORD; // different versions of psapi.pas floating around
var
i,j,pidNeeded,modNeeded : Integer;
PIDList : array[0..1000] of Integer; // 1000 should be enough
MODList : array[0..1000] of HInst;
PIDName : array [0..MAX_PATH - 1] of char;
MODName : array [0..MAX_PATH - 1] of char;
PH : THandle;
begin
// fill an array with process ids
if not enumprocesses (@PIDList, 1000, pidNeeded) then
begin
ListBox1.Items.Add('Need psapi.dll');
exit;
end;
// now open each process and its modules
for i := 0 to (pidNeeded div sizeof (Integer)- 1) do
begin
// get a handle to the process
PH := OpenProcess (PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False,
PIDList);
if PH <> 0 then
begin
// print the process name
if GetModuleBaseName (PH, 0, PIDName, sizeof (PIDName)) > 0 then
begin
ListBox1.Items.Add('process : ' + PIDName);
// fill an array of modules associated with this process
if not EnumProcessModules (PH,@MODList,1000, modNeeded) then modNeeded:= 0;
// print the modules in the list
for j := 0 to (modNeeded div sizeof (hInst) - 1) do
if GetModuleFileNameEx (PH, MODList[j], MODName,sizeof(MODName)) > 0 then
begin
ListBox1.Items.Add(' module: ' + MODName);
if LowerCase(trim(ExtractFileName(ModName))) = LowerCase('MHK.dll') then Caption := ('Keyboard hook already running');
end;
if PH > 0 then CloseHandle(PH);
end;
end;
end;
end;
end.