var FSnapshotHandle, ProcessHndle: THandle; FProcessEntry32: TProcessEntry32; ContinueLoop: BOOL; ProcessID : integer; ItemName : String; begin FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); Result := True; Try FProcessEntry32.dwSize := Sizeof(FProcessEntry32); ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32); while integer(ContinueLoop) <>0 do begin ItemName := ExtractFileName(FProcessEntry32.szExeFile); ProcessID := FProcessEntry32.th32ProcessID; If UpperCase(ItemName) = 'QQ.EXE' Then//比較进程的名稱 Begin ProcessHndle:=OpenProcess(PROCESS_ALL_ACCESS,BOOL(0),ProcessID); //进程的句柄 End; ContinueLoop :=Process32Next(FSnapshotHandle,FProcessEntry32); end; Finally CloseHandle(FSnapshotHandle); End; end;
先用HelpTool弄个进程快照,然后遍历进程,找到目标进程,然后用FindWindow获得句柄
补充一点,获得焦点需要WM_FOCUS消息…… 要获得焦点改变的信息,就需要hook这个消息
给你一段参考代码,获得进程及模块的树形结构,放到TV控件中uses Tlhelp32; procedure ProcessEnum(TV:TTreeView); var ProcessList :Thandle; pe :TPROCESSENTRY32; node :TTreenode; processnumber :integer; procedure ModuleEnum(processid:Dword); var ModuleList :Thandle; pm :TMODULEENTRY32; begin ModuleList:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processID); pm.dwSize:=sizeof(TMODULEENTRY32); if module32first(ModuleList,pm) then begin TV.Items.addchild(node,pm.szexepath); while module32next(ModuleList,pm) do TV.items.addchild(node,pm.szexepath); end; CloseHandle(ModuleList); end; // ModuleEnumbegin // ProcessEnum processnumber:=0; TV.Items.Clear; ProcessList:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pe.dwSize:=sizeof(TPROCESSENTRY32); if process32first(ProcessList,pe) then begin node:=TV.Items.Add(nil,pe.szexefile); ModuleEnum(pe.th32ProcessID); inc(processnumber); while process32next(ProcessList,pe) do begin node:=TV.Items.Add(nil,pe.szexefile); ModuleEnum(pe.th32ProcessID); inc(processnumber); end; end; //edit1.text:=’系统进程:’+inttostr(processnumber); CloseHandle(ProcessList); end;
按照5楼的方法,遍历进程 我整理下,遍历并取得进程创建的时间,是不是可以根据进程创建的时间而获得刚刚启动的程序进程呢? 代码如下: TProcessInfo = Record ExeFile : String; ProcessID : DWORD; end; pProcessInfo = ^TProcessInfo; ... MyProcess : Tlist; ... procedure TForm1.btn3Click(Sender: TObject); var p : pProcessInfo; IsLoopContinue:BOOL; FSnapshotHandle,hProcess:THandle; FProcessEntry32:TProcessEntry32; lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: TFileTime; function GetTimeString(AFileTime: TFileTime): string; var ASysTime: TSystemTime; begin FileTimeToSystemTime(AFileTime, ASysTime); with ASysTime do Result := Format('%d-%d-%d %d:%d:%d.%d', [wYear, wMonth, wDay, wHour,wMinute, wSecond, wMilliseconds]); end; begin MyProcess := TList.Create; // 保存进程信息的列表 MyProcess.Clear; // 初始化列表 lst1.Clear;//在form上的listbox,用来显示进程列表 FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 创建进程快照 FProcessEntry32.dwSize:=Sizeof(FProcessEntry32); // 设置结构的大小 IsLoopContinue:=Process32First(FSnapshotHandle,FProcessEntry32); //取得第一个进程 while integer(IsLoopContinue)<>0 do begin New(p); p.ExeFile := FProcessEntry32.szExeFile; p.ProcessID := FProcessEntry32.th32ProcessID; hProcess := OpenProcess(PROCESS_QUERY_INFORMATION, False, p.ProcessID);//取进程的句柄 GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);//获得进程的创建时间 lst1.Items.Add(p.ExeFile+' '+ GetTimeString(lpCreationTime)); //把进程名称和创建时间加到listbox //疑问:是不是可以根据这个创建时间的大小来判断刚才点击桌面的程序?如果这样,是不是要放个Ttime控件来时时刷新这段代码? CloseHandle(hProcess);//释放进程句柄 MyProcess.Add(p); // 添加到进程列表 IsLoopContinue:=Process32Next(FSnapshotHandle,FProcessEntry32); // 继续枚举 end; CloseHandle(FSnapshotHandle); // end; 欢迎大家继续讨论
我想做个进程监控程序,实时监控当前程序,比如,当用户单击桌面的“IE”时,我就获进IE的进程句柄,当用户单击运行QQ时,我就获得QQ进程的句柄
如此类堆,当用户执行某程序,根据我的程序监控就实时花得这个程序的进程句柄
请问如何实现,欢迎大家讨论
如有代码贴上参考最好
FSnapshotHandle, ProcessHndle: THandle;
FProcessEntry32: TProcessEntry32;
ContinueLoop: BOOL;
ProcessID : integer;
ItemName : String;
begin
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
Result := True;
Try
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop) <>0 do
begin
ItemName := ExtractFileName(FProcessEntry32.szExeFile);
ProcessID := FProcessEntry32.th32ProcessID;
If UpperCase(ItemName) = 'QQ.EXE' Then//比較进程的名稱
Begin
ProcessHndle:=OpenProcess(PROCESS_ALL_ACCESS,BOOL(0),ProcessID); //进程的句柄
End; ContinueLoop :=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
Finally
CloseHandle(FSnapshotHandle);
End;
end;
要获得焦点改变的信息,就需要hook这个消息
给你一段参考代码,获得进程及模块的树形结构,放到TV控件中uses Tlhelp32; procedure ProcessEnum(TV:TTreeView);
var
ProcessList :Thandle;
pe :TPROCESSENTRY32;
node :TTreenode;
processnumber :integer;
procedure ModuleEnum(processid:Dword);
var
ModuleList :Thandle;
pm :TMODULEENTRY32;
begin
ModuleList:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processID);
pm.dwSize:=sizeof(TMODULEENTRY32);
if module32first(ModuleList,pm) then
begin
TV.Items.addchild(node,pm.szexepath);
while module32next(ModuleList,pm) do
TV.items.addchild(node,pm.szexepath);
end;
CloseHandle(ModuleList);
end; // ModuleEnumbegin // ProcessEnum
processnumber:=0;
TV.Items.Clear;
ProcessList:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize:=sizeof(TPROCESSENTRY32);
if process32first(ProcessList,pe) then
begin
node:=TV.Items.Add(nil,pe.szexefile);
ModuleEnum(pe.th32ProcessID);
inc(processnumber);
while process32next(ProcessList,pe) do
begin
node:=TV.Items.Add(nil,pe.szexefile);
ModuleEnum(pe.th32ProcessID);
inc(processnumber);
end;
end;
//edit1.text:=’系统进程:’+inttostr(processnumber);
CloseHandle(ProcessList);
end;
我整理下,遍历并取得进程创建的时间,是不是可以根据进程创建的时间而获得刚刚启动的程序进程呢?
代码如下:
TProcessInfo = Record
ExeFile : String;
ProcessID : DWORD;
end;
pProcessInfo = ^TProcessInfo;
...
MyProcess : Tlist;
...
procedure TForm1.btn3Click(Sender: TObject);
var
p : pProcessInfo;
IsLoopContinue:BOOL;
FSnapshotHandle,hProcess:THandle;
FProcessEntry32:TProcessEntry32;
lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: TFileTime;
function GetTimeString(AFileTime: TFileTime): string;
var
ASysTime: TSystemTime;
begin
FileTimeToSystemTime(AFileTime, ASysTime);
with ASysTime do
Result := Format('%d-%d-%d %d:%d:%d.%d', [wYear, wMonth, wDay, wHour,wMinute, wSecond, wMilliseconds]); end;
begin
MyProcess := TList.Create; // 保存进程信息的列表
MyProcess.Clear; // 初始化列表
lst1.Clear;//在form上的listbox,用来显示进程列表
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 创建进程快照
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32); // 设置结构的大小
IsLoopContinue:=Process32First(FSnapshotHandle,FProcessEntry32); //取得第一个进程
while integer(IsLoopContinue)<>0 do
begin
New(p);
p.ExeFile := FProcessEntry32.szExeFile;
p.ProcessID := FProcessEntry32.th32ProcessID;
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION, False, p.ProcessID);//取进程的句柄
GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);//获得进程的创建时间
lst1.Items.Add(p.ExeFile+' '+ GetTimeString(lpCreationTime)); //把进程名称和创建时间加到listbox
//疑问:是不是可以根据这个创建时间的大小来判断刚才点击桌面的程序?如果这样,是不是要放个Ttime控件来时时刷新这段代码?
CloseHandle(hProcess);//释放进程句柄
MyProcess.Add(p); // 添加到进程列表
IsLoopContinue:=Process32Next(FSnapshotHandle,FProcessEntry32); // 继续枚举
end;
CloseHandle(FSnapshotHandle); //
end;
欢迎大家继续讨论
关键是我并不知道用户点了桌面的哪个程序,所以也无法用进程名来对比,现在我只想取得用户当前打开应用程序的进程名柄(这个程序是未知的)
再说说下我的目的:我想取得这个句柄后调整进程的优先级以达到加快进程的启动速度
unit jdspy;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;type
TFrmjdSpy = class(TForm)
Timer: TTimer;
Shape: TShape;
HandleLabel: TLabel;
ClassNameLabel: TLabel;
TitleLabel: TLabel;
HandleText: TLabel;
ClassNameText: TLabel;
TitleText: TLabel;
ColorLabel: TLabel;
RGBColorText: TLabel;
AboutButton: TButton;
DelphiColorText: TLabel;
HTMLColorText: TLabel;
procedure FormCreate(Sender: TObject);
procedure TimerTimer(Sender: TObject);
private
public
end;var
FrmjdSpy: TFrmjdSpy;implementation{$R *.DFM}function GetWorkAreaRect: TRect;
begin
SystemParametersInfo(SPI_GETWORKAREA, 0, @Result, 0);
end;procedure TFrmjdSpy.FormCreate(Sender: TObject);
var
MRect: TRect;
begin
{ 把窗口定位在工作区右下角 }
MRect := GetWorkAreaRect;
Left := MRect.Right - Width;
Top := MRect.Bottom - Height;
{ 使窗口总在最前 }
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
end;procedure TFrmjdSpy.TimerTimer(Sender: TObject);
var
Pos: TPoint;
Handle: HWND;
ScreenDC: HDC;
Buf: array[0..1024] of Char;
ScreenColor: COLORREF;
begin
GetCursorPos(Pos); // 得到当前光标位置
Handle := WindowFromPoint(Pos); // 返回当前位置的句柄
HandleText.Caption := IntToStr(Handle);
GetClassName(Handle, Buf, 1024); // 得到类名
ClassNameText.Caption := Buf;
SendMessage(Handle, WM_GETTEXT, 33, Integer(@Buf)); // 得到标题
TitleText.Caption := Buf;
{ 得到光标处点的颜色 }
ScreenDC := GetDC(0);
ScreenColor := GetPixel(ScreenDC, Pos.X, Pos.Y);
Shape.Brush.Color := TColor(ScreenColor);
RGBColorText.Caption := '红: ' + IntToStr(GetRValue(ScreenColor)) +
' 绿: ' + IntToStr(GetGValue(ScreenColor)) + ' 蓝: ' +
IntToStr(GetBValue(ScreenColor));
ReleaseDC(0, ScreenDC);
DelphiColorText.Caption := Format('Delphi 值:$00%2.2x%2.2x%2.2x', [GetBValue(ScreenColor),
GetGValue(ScreenColor), GetRValue(ScreenColor)]);
HTMLColorText.Caption := Format('HTML 值:#%2.2x%2.2x%2.2x', [GetRValue(ScreenColor),
GetGValue(ScreenColor), GetBValue(ScreenColor)]);
end;end.
Windows, Messages;var
HookHandle: HHOOK;function HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
if PCWPSTRUCT(lParam)^.message = WM_CREATE then
begin
//这里获得的 PCREATESTRUCT(PCWPSTRUCT(lParam)^.lParam)^.hInstance 就是句柄。
end;
end;function InstallHook(): BOOL; stdcall; export;
begin
HookHandle := SetWindowsHookEx(WH_CALLWNDPROC, @HookProc, HInstance, 0);
result := HookHandle > 0;
end;function UninstallHook(): BOOL; stdcall; export;
begin
Result := UnhookWindowsHookEx(HookHandle);
HookHandle := 0;
end;exports
InstallHook,UninstallHook;begin
end.我这里没有Delphi,参考以前代码写的,或许书写有错误,但思路就是这样。