我想做个进程监控程序,实时监控当前程序,比如,当用户单击桌面的“IE”时,我就获进IE的进程句柄,当用户单击运行QQ时,我就花得QQ进程的句柄
如果类堆,当用户某程序,根据我的程序监控就实时花得这个程序的进程句柄
请问如何实现,欢迎大家讨论
如有代码贴上参考最好

解决方案 »

  1.   

    不好意思,打字太快没仔细看,错别字很多,改下:
    我想做个进程监控程序,实时监控当前程序,比如,当用户单击桌面的“IE”时,我就获进IE的进程句柄,当用户单击运行QQ时,我就获得QQ进程的句柄 
    如此类堆,当用户执行某程序,根据我的程序监控就实时花得这个程序的进程句柄 
    请问如何实现,欢迎大家讨论 
    如有代码贴上参考最好
      

  2.   

    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; 
      

  3.   

    先用HelpTool弄个进程快照,然后遍历进程,找到目标进程,然后用FindWindow获得句柄
      

  4.   

    补充一点,获得焦点需要WM_FOCUS消息……
    要获得焦点改变的信息,就需要hook这个消息
      

  5.   


    给你一段参考代码,获得进程及模块的树形结构,放到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;
      

  6.   

    按照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;
    欢迎大家继续讨论
      

  7.   

    再回rouqing :
    关键是我并不知道用户点了桌面的哪个程序,所以也无法用进程名来对比,现在我只想取得用户当前打开应用程序的进程名柄(这个程序是未知的)
    再说说下我的目的:我想取得这个句柄后调整进程的优先级以达到加快进程的启动速度
      

  8.   


    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.
      

  9.   

    HOOK WM_CREATE消息,但必须在DLL中。
      

  10.   

    library uMain;uses
      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,参考以前代码写的,或许书写有错误,但思路就是这样。