现系统中运行有两个相同名字的程序,用FindWindow 只能获得其中一个的句柄,问如果才能获取另一个的???或 我用 TLHelp32 取得了进程的 ID 可否根据这 ID 取该 句柄或类名???

解决方案 »

  1.   

    名字相同,类不一定相同啊。
    如果类形同窗口里面的结构总不相同了吧,你可以用Findwindowex 和 getwindow 来分窗口的结构来区别两个窗口。
      

  2.   

    var s: array[0..127] of Char
    GetClassName(Handle,s)
    就可以获取类名
      

  3.   

    这样就可以了var
      Wnd1,Wnd2:HWND;
    begin
      Wnd1:=FindWindow('类名',nil);
      Wnd2:=FindWindowEx(0,Wnd1,'类名',nil);
    end;
      

  4.   

    unit Unit1;
    interface
    uses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  StdCtrls, ComCtrls;const  KILL_NOERR = 0;  KILL_NOTSUPPORTED = -1;  KILL_ERR_OPENPROCESS = -2;  KILL_ERR_TERMINATEPROCESS = -3;
      ENUM_NOERR = 0;  ENUM_NOTSUPPORTED = -1;  ENUM_ERR_OPENPROCESSTOKEN = -2;  ENUM_ERR_LookupPrivilegeValue = -3;  ENUM_ERR_AdjustTokenPrivileges = -4;
      SE_DEBUG_NAME = 'SeDebugPrivilege';type  TForm1 = class(TForm)    Button1: TButton;    TreeView1: TTreeView;    Memo1: TMemo;    Button2: TButton;    procedure Button1Click(Sender: TObject);    procedure FormClose(Sender: TObject; var Action: TCloseAction);    procedure TreeView1MouseDown(Sender: TObject; Button: TMouseButton;      Shift: TShiftState; X, Y: Integer);    procedure TreeView1DblClick(Sender: TObject);    procedure FormCreate(Sender: TObject);    procedure Button2Click(Sender: TObject);  private    { Private declarations }
      public    { Public declarations }  end;
    var  Form1: TForm1;  ProcessNameList,ProcessIDList,FullNameList:TStrings;implementation
    {$R *.DFM}function EnumProcesses(lpidProcess,cb,cbNeeded:dword):         integer;stdcall;external 'PSAPI.DLL';function EnumProcessModules(hProcess:THandle;lphModule:HMODULE;cb,lpcbNeeded:Dword):         integer;stdcall;external 'PSAPI.DLL';function GetModuleBaseNameA(hProcess:THandle;hModule:HMODULE;lpBaseName:pchar;nSize:DWord):         integer;stdcall;external 'PSAPI.DLL';function GetModuleFileNameExA(hProcess:THandle;hModule:HMODULE;lpFilename:pchar;nSize:DWord):         integer;stdcall;external 'PSAPI.DLL';
    procedure ErrorMessage;var   MsgBuf:string;begin  FormatMessage(      FORMAT_MESSAGE_ALLOCATE_BUFFER or      FORMAT_MESSAGE_FROM_SYSTEM or      FORMAT_MESSAGE_IGNORE_INSERTS,      nil,      GetLastError(),      LANG_NEUTRAL,//MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language      @MsgBuf,      sizeof(MsgBuf),      nil  );  MessageBox(0,pchar(MsgBuf),' 错误 ',MB_OK);  raise EAbort.Create ('') ;end;
    procedure GetTokenInfo(ProcessID:THandle);var   InfoBuffer:TTokenPrivileges;   i:Integer;   ucPrivilegeName:pchar;   dwPrivilegeNameSize,dwInfoBufferSize:DWord;   PrivilegesList:TStrings;   hToken,hProcess : THANDLE;   s:string;   p:pchar;begin     //get process handle from process id     hProcess := OpenProcess( PROCESS_ALL_ACCESS,                                   true, processID );    if hProcess=0 then        ErrorMessage;     //get token handle from process handle     if (OpenProcessToken(hProcess,             TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_READ, hToken) = false) then     begin          ErrorMessage;     end;
         dwInfoBufferSize:=0;     if GetTokenInformation(hToken,TokenPrivileges,@InfoBuffer,                         sizeof(TTokenPrivileges),dwInfoBufferSize)=false then     begin          ErrorMessage;     end;{     if PrivilegesList=nil then        PrivilegesList:=TStringList.Create     else         PrivilegesList.Clear; }     ucPrivilegeName:=strAlloc(128);
         exit;     s:='bbbb';     strPcopy(ucPrivilegeName,s);     //ucPrivilegeName:='aaa';     s:=strpas(ucPrivilegeName);     showmessage(s);
         dwPrivilegeNameSize:=1000;     for i:=0 to InfoBuffer.PrivilegeCount-1  do     begin     if LookupPrivilegeName(nil,InfoBuffer.Privileges[i].Luid,               ucPrivilegeName,dwPrivilegeNameSize)=false then     begin          ErrorMessage;     end;     //PrivilegesList.Add (strpas(ucPrivilegeName));     //Form1.Memo1.Lines.Add(strpas(ucPrivilegeName));          //s:=strpas(ucPrivilegeName);          showmessage(s);     end;     strDispose(ucPrivilegeName);     //Form1.Memo1.Lines:=PrivilegesList;
         CloseHandle( hProcess );{     if PrivilegesList<>nil then   PrivilegesList.Free ;   }end;
    function  EnableDebugPrivilegeNT : integer;var  hToken : THANDLE;  DebugValue : TLargeInteger;  tkp : TTokenPrivileges ;  ReturnLength : DWORD;  PreviousState: TTokenPrivileges;begin  if (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_READ, hToken) = false) then    result := ENUM_ERR_OPENPROCESSTOKEN  else  begin    if (LookupPrivilegeValue(nil, SE_DEBUG_NAME, DebugValue) = false) then      result := ENUM_ERR_LookupPrivilegeValue    else    begin      ReturnLength := 0;      tkp.PrivilegeCount := 1;      tkp.Privileges[0].Luid := DebugValue;      tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;      AdjustTokenPrivileges(hToken, false, tkp, SizeOf(TTokenPrivileges),PreviousState , ReturnLength);      if (GetLastError <> ERROR_SUCCESS) then   result := ENUM_ERR_AdjustTokenPrivileges      else   result := ENUM_NOERR;    end;  end;end;
    function Kill_By_Pid(pid : longint) : integer;var  hProcess : THANDLE;  TermSucc : BOOL;begin    hProcess := OpenProcess(PROCESS_ALL_ACCESS, true, pid);    if (hProcess = 0) then // v 1.2 : was =-1    begin      result := KILL_ERR_OPENPROCESS;    end    else    begin      TermSucc := TerminateProcess(hProcess, 0);      if (TermSucc = false) then        result := KILL_ERR_TERMINATEPROCESS      else        result := KILL_NOERR;    end;end;
      

  5.   

    //接上procedure UpdateTreeView(Tree:TTreeView);var   i:integer;   MyNode:TTreeNode;begin     with Tree.Items do     begin          Clear;          if MyNode<>nil then             MyNode:=nil ;
              for i:=0 to ProcessNameList.Count-1 do          begin               if (MyNode=nil)or(UpperCase(copy(processNameList[i],length(processNameList[i])-2,3))='EXE') then                  MyNode:=add(nil,processNameList[i])               else                  AddChild(MyNode,processNameList[i]);          end;     end;end;
    procedure PrintProcessNameAndID(processID: DWORD);var//   szProcessName:ARRAY[0..1024] OF CHAR;   szFullName:ARRAY[0..1024] OF CHAR;   szModName :ARRAY[0..1024] OF CHAR;   hProcess  : THandle;   hMods     :array [0..1024] of dword;   cbNeeded,cMod  : DWORD ;   i       : Integer;begin     // Get a handle to the process.    hProcess := OpenProcess( PROCESS_QUERY_INFORMATION or                                   PROCESS_VM_READ,                                   FALSE, processID );    // Get the process name.    szModName := 'unknown';    szFullName := 'unknown';    if ( hProcess<>0 ) then    begin         if EnumProcessModules( hProcess, dword(@hMods), sizeof(hMods),dword(@cbNeeded))<>0 then         begin//            GetModuleBaseNameA( hProcess, hMod, szProcessName,sizeof(szProcessName) );//            GetModuleFileNameExA(hProcess, hMod, szFullName,sizeof(szFullName));            cMod:=cbNeeded div sizeof(HMODULE);            for  i := 0 to (cMod-1) do            begin              // Get the full path to the module's file.              GetModuleBaseNameA( hProcess, hMods[i], szModName,sizeof(szModName));              GetModuleFileNameExA( hProcess, hMods[i], szFullName,sizeof(szModName));              ProcessNameList.Add (StrPas(szModName));              FullNameList.Add (StrPas(szFullName));            end;         end;    end;
        // Print the process name and identifier.
        //Form1.Memo1.Lines.Add (StrPas(szProcessName));//    ProcessNameList.Add (StrPas(szProcessName));//    FullNameList.Add (StrPas(szFullName));
        CloseHandle( hProcess );
    end;
    procedure TForm1.Button1Click(Sender: TObject);var    cbNeeded, cProcesses:dword;    aProcesses: array [0..1024] of dword;    i:Cardinal;begin     if EnumProcesses( Dword(@aProcesses), sizeof(aProcesses), Dword(@cbNeeded))<>0 then     begin          cProcesses := cbNeeded div sizeof(DWORD);     end     else         showmessage(inttostr(GetLastError));
         if ProcessIDList<>nil then          processidlist.Clear     else         ProcessIDList:=TStringList.Create;     if ProcessNameList<>Nil then        ProcessNameList.Clear     else         ProcessNameList:=Tstringlist.Create;
         if FullNameList<>Nil then        FullNameList.Clear     else         FullNameList:=TStringList.Create ;     for i:=0 to cprocesses-1 do         processidlist.Add(intToStr(aProcesses[i]));
         for i:=0 to cProcesses-1 do     begin          PrintProcessNameAndID( strtoint(ProcessIDList[i]));     end;//     Memo1.lines:=ProcessNameList;     UpdateTreeView(Form1.TreeView1);end;
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);begin     if ProcessIDList<>Nil then        ProcessIDList.Free;     if ProcessNameList<>nil then        ProcessNameList.Free ;     if FullNameList<>Nil then        FullNameList.Free ;end;
    procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;  Shift: TShiftState; X, Y: Integer);var   MyNode:TTreeNode;begin
         MyNode:=TreeView1.GetNodeAt(x,y);     if MyNode<>nil then     begin          MyNode.Selected :=true;          if MyNode.HasChildren then          begin             Caption:='['+ ProcessIDList[MyNode.index]+ ']'+FullNameList[MyNode.AbsoluteIndex];             GetTokenInfo(strToint(ProcessIDList[MyNode.Index]));          end          else              Caption:=FullNameList[MyNode.AbsoluteIndex];     end;
    end;
    procedure TForm1.TreeView1DblClick(Sender: TObject);var   MyNode:TTreeNode;begin     MyNode:= TreeView1.Selected;     if (MyNode<>Nil)and(MyNode.HasChildren) then     begin          showmessage(intTostr(Kill_By_Pid(strToInt(ProcessIDList[MyNode.Index]))));     end;
    end;
    procedure TForm1.FormCreate(Sender: TObject);begin     EnableDebugPrivilegeNT;end;
    procedure TForm1.Button2Click(Sender: TObject);var   s:string ;   p:Pchar;begin     p:=strAlloc(128);     strcopy(p,'aa');     //p:='aaa';     s:=strpas(p);     showmessage(s);
         strDispose(p);end;
    end.