如何及时发现进程 Notepad.exe? ( 积分: 100 )

  • 主题发起人 主题发起人 求学鸟
  • 开始时间 开始时间

求学鸟

Unregistered / Unconfirmed
GUEST, unregistred user!
我现有一个工程 MyApp,是开机自动运行的。我希望它能够实时监控用户使用情况,
如果发现用户运行了某一进程(如记事本程序 Notepad.exe),则弹出窗体 frmNotice。
有点类似于一些防火墙软件在检测到木马时会弹出警告。

为此,我设计了两套实现方案:

1. 设置一个 Timer,定时检查进程列表,如果发现 Notepad.exe 在列表中则
作出反应;

2. 捕捉 Notepad.exe 运行时发出的消息加以识别处理;


显然第一种方案效率较低,并且反应慢,不如方案二快速有效。因此我想选择方案二,
但对于 应该捕捉何种消息 、如何处理消息 我知之甚少。所以希望大家介绍一二。
如果哪位有更好的思路,更是求之不得。
 
我现有一个工程 MyApp,是开机自动运行的。我希望它能够实时监控用户使用情况,
如果发现用户运行了某一进程(如记事本程序 Notepad.exe),则弹出窗体 frmNotice。
有点类似于一些防火墙软件在检测到木马时会弹出警告。

为此,我设计了两套实现方案:

1. 设置一个 Timer,定时检查进程列表,如果发现 Notepad.exe 在列表中则
作出反应;

2. 捕捉 Notepad.exe 运行时发出的消息加以识别处理;


显然第一种方案效率较低,并且反应慢,不如方案二快速有效。因此我想选择方案二,
但对于 应该捕捉何种消息 、如何处理消息 我知之甚少。所以希望大家介绍一二。
如果哪位有更好的思路,更是求之不得。
 
给你第一种方案的方法,第二种方案好像有点难度。

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls,TLHelp32;

type
TProcessInfo = Record
ExeFile : String;
ProcessID : DWORD;
end;
pProcessInfo = ^TProcessInfo;

type
TForm1 = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure show_msg;
var
p: pProcessInfo;
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
New(p);
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop)<>0 do
begin
p.ExeFile:= FProcessEntry32.szExeFile;
if UpperCase(p.ExeFile)='NOTEPAD.EXE' then
begin
showmessage('found notepad');
halt;
end;
ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
show_msg;
end;

end.
 
var
hCurrentWindow: HWnd;
szText: array[0..254] of char;
begin
hCurrentWindow := GetWindow(Handle, GW_HWNDFIRST);
while hCurrentWindow <&gt
0 do
begin
if (GetWindowText(hCurrentWindow, @szText, 255)>0)and(upper(strpas(@sztext))='NOTEPAD.EXE ')then
sendmessage(hCurrentWindow,WM_CLOSE,0,0);
hCurrentWindow:=GetWindow(hCurrentWindow, GW_HWNDNEXT);
end;
 
使用钩子程序应该是可以的
不要用Timer控件,太好资源了
用Event机制,然后WaitForSingleObject挂起进程
具体的例子可以参看Jedi的DirectX头文件翻译中的高精度计时器的源码
 
weiliu,
辛苦你了,写了这么详细的代码。如果方案二难以实现的话,我会采用你的代码的。
谢谢!

011101,
你提供的代码测试无法通过——运行 Notepad.exe 程序无反应。我推测用遍历所
有窗体的编写思路可能有些问题,希望你考虑。
另外有一点小小的错误:只有 UpperCase 函数而不存在 Upper 函数。

cst_zf,
我认为你的解答是最佳的,不过很可惜我水平不够,理解很有困难。我会根据你提供
的信息去寻找有关知识。同时,不知你是否可以提供更详细些的关于"Jedi的DirectX头
文件翻译"的信息?
谢谢!
 
你说的问题在windows Api编程一书有详细例程,你研究一下就行。
大约在窗口消息章节中。
 
楼主,你想实现的功能,这几天我也在思考,你去2ccc.com去找<<delphi下深入windows编程>>这本书,应该对你有帮助,不过好象不是太全
 
建议使用Timer来间隔检查进程列表,检查列表这个动作并不耗时,我在我的一个软件中就是用这种方法来监控Notepad.exe,我是每隔0.5秒检查一次,从进程监管理器上看,程序耗时基本上为0%。
还有一种方法,应该就是用利用全局钩子了,过滤所有的Windows消息,需要做成DLL形式,以映射到每个进程,比较麻烦。

 
感谢各位献计献策,让我也学了不少。现在我对问题的答案基本上有底了:暂时先用
Timer ,对消息机制再研究研究,日后再作打算。
 
后退
顶部