请问用什么方法可以运行一个外部的EXE并返回它的Handle?(200分)(200分)

  • 主题发起人 主题发起人 bundur
  • 开始时间 开始时间
B

bundur

Unregistered / Unconfirmed
GUEST, unregistred user!
请问用什么方法可以运行一个外部的EXE并返回它的Handle?<br>WinExec 和 ShellExecute 返回不是该EXE的Handle<br>ShellExecuteEx 也不是和 CreateProcess 一样返回的是 Process Handle<br>到底要如何才可以返回和 FindWindow 所返回的一样的 Handle?<br>或者如何通过 Process Handle 得到 Application Handle 或 MainForm Handle<br>
 
用函数WindowFromPoint &nbsp; (api)
 
WindowFromPoint<br>这个不大现实,因为执行的程序可能是最小化的,也可以是后台(隐藏)运行的。<br>还在,即使是有窗口出现,什么时候出现,有没有别的窗口在它之上等都不可控。
 
没搞懂你说的意思?<br>
 
参考<br>http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q242/3/08.asp&amp;NoWebContent=1<br><br>HOWTO: Find a Window Handle from an Instance Handle
 
type<br>&nbsp; PProcessWindowInfo=^TProcessWindowInfo;<br>&nbsp; TProcessWindowInfo=record<br>&nbsp; &nbsp; ProcessID:DWORD;<br>&nbsp; &nbsp; Handle:THandle;<br>&nbsp; end;<br><br>function CheckProcessWindow(Handle: HWND; Info: Pointer): BOOL; stdcall;<br>var<br>&nbsp; ProcessID:DWORD;<br>begin<br>&nbsp; GetWindowThreadProcessId(Handle,ProcessID);<br>&nbsp; Result := ProcessID&lt;&gt;PProcessWindowInfo(Info)^.ProcessID;<br>&nbsp; if not Result then<br>&nbsp; &nbsp; PProcessWindowInfo(Info)^.Handle:=Handle;<br>end;<br><br>function FindProcessWindow(ProcessID:DWORD):THandle;<br>&nbsp; //查找进程当前窗口,若成功,返回窗口Handle,否则返回0<br>var<br>&nbsp; Info:TProcessWindowInfo;<br>begin<br>&nbsp; Info.ProcessID:=ProcessID;<br>&nbsp; Info.Handle:=0;<br>&nbsp; EnumWindows(@CheckProcessWindow, Longint(@Info));<br>&nbsp; Result:=Info.Handle;<br>end;<br><br>function FindExeWindow(const FileName:string):THandle;<br>&nbsp; //查找EXE文件当前窗口,若成功,表明该文件已运行,返回窗口Handle,否则返回0<br>var<br>&nbsp; ReleFileName:string;<br>&nbsp; CPReleFileName:boolean;<br>&nbsp; TempList:Classes.TStringList;<br>&nbsp; index:integer;<br>begin<br>&nbsp; ReleFileName:=FileName; //GetRealPath(FileName);<br>&nbsp; CPReleFileName:=not SameText(ReleFileName,FileName);<br>&nbsp; TempList:=TStringList.Create;<br>&nbsp; try<br>&nbsp; &nbsp; GetProcesses(TempList,True);<br>&nbsp; &nbsp; Result:=0;<br>&nbsp; &nbsp; for Index:=0 to TempList.Count-1 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if SameText(TempList[Index],FileName) or<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(CPReleFileName and SameText(TempList[Index],ReleFileName)) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=FindProcessWindow(DWORD(TempList.Objects[Index]));<br>&nbsp; &nbsp; &nbsp; &nbsp; Break;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; finally<br>&nbsp; &nbsp; TempList.Free;<br>&nbsp; end;<br>end;<br>
 
同意 龙丹
 
The FindExecutable function retrieves the name and handle to the executable (.EXE) file associated with the specified filename. <br><br>HINSTANCE FindExecutable(<br><br>&nbsp; &nbsp;LPCTSTR lpFile, &nbsp;// pointer to string for filename<br>&nbsp; &nbsp;LPCTSTR lpDirectory, &nbsp;// pointer to string for default directory<br>&nbsp; &nbsp;LPTSTR lpResult &nbsp;// pointer to buffer for string for executable file on return
 
To: 龙丹<br>您的方法通过枚举当前进程和当前窗口进行匹配,不失为一种好办法.<br>但是 GetRealPath 和 GetProcesses 两个函数上哪儿找?<br><br>To: tseug<br>我试了一下, 用 CreateProcess 和 ShellExecuteEx 得到的 hProcess<br>和用 GetWindowThreadProcessId 得到的 hProcess 是不一样的! <br>( WinExec 和 ShellExecute 更不用说了 )<br>也就是说不能通过 CreateProcess 和 ShellExecuteEx 得到的 hProcess <br>再由 GetWindowThreadProcessId 来得到 Window Handle 的.<br>我想知道的正是能由 &nbsp;CreateProcess 和 ShellExecuteEx 得到的 hProcess <br>推出Window Handle 的.<br><br>To: 唐僧肉<br>能解释一下该函数的三个参数如何使用吗?<br><br><br>
 
龙龙龙...............龙小姐.<br>你你你...............你的代码.<br>通通通...............不过....
 
type<br>&nbsp; PEnumInfo = ^TEnumInfo;<br>&nbsp; TEnumInfo = record<br>&nbsp; &nbsp; ProcessID : DWORD;<br>&nbsp; &nbsp; HWND &nbsp; &nbsp; &nbsp;: THandle;<br>&nbsp; end;<br><br>function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;<br>var<br>&nbsp; PID : DWORD;<br>begin<br>&nbsp; GetWindowThreadProcessID(Wnd, @PID);<br>&nbsp; Result := (PID &lt;&gt; EI.ProcessID) or<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (not IsWindowVisible(WND)) or<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (not IsWindowEnabled(WND));<br><br>&nbsp; if not result then EI.HWND := WND;<br>end;<br><br>function FindMainWindow(PID: DWORD): DWORD;<br>var<br>&nbsp; EI : TEnumInfo;<br>begin<br>&nbsp; EI.ProcessID := PID;<br>&nbsp; EI.HWND &nbsp; &nbsp; &nbsp;:= 0;<br>&nbsp; EnumWindows(@EnumWindowsProc, Integer(@EI));<br>&nbsp; Result := EI.HWND;<br>end;<br><br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; SI : TStartupInfo;<br>&nbsp; PI : TProcessInformation;<br>&nbsp; H &nbsp;: &nbsp;THandle;<br>&nbsp; S &nbsp;: &nbsp;String;<br>begin<br>&nbsp; ZeroMemory(@SI, SizeOf(SI));<br>&nbsp; ZeroMemory(@PI, SizeOf(PI));<br>&nbsp; SI.cb &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= SizeOf(SI);<br>if CreateProcess(nil,'CALC.EXE', nil, nil, FALSE, 0 ,nil,nil, SI, PI) then<br>&nbsp; begin<br>&nbsp; //注意!<br>&nbsp; WaitForInputIdle(PI.hProcess, INFINITE);<br><br>&nbsp; H := FindMainWindow(PI.dwProcessID);<br>&nbsp; if H &gt; 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; SetLength(S, 255);<br>&nbsp; &nbsp; GetWindowText(H, PChar(S), 255);<br>&nbsp; &nbsp; SetLength(S, StrLen(PChar(S)));<br>&nbsp; &nbsp; ShowMessage(S);<br>&nbsp; &nbsp; end;<br><br>&nbsp; CloseHandle(PI.hProcess);<br>&nbsp; CloseHandle(PI.hThread);<br>&nbsp; end;<br>end;<br>end.<br>
 
呵呵,不好意思,不好意思,在别的单元里,忘拷贝了<br><br>GetRealPath {取真实路径} 可以不管,直接用FileName好了<br><br>procedure GetProcesses(List:TStrings; IDOnly:boolean=False);<br>&nbsp; //取进程清单,若IDOnly=True,则List是进程主模块文件路径,List.Objects是进程ID<br>&nbsp; //若IDOnly=False,则List是进程主模块文件名,List.Objects是指向TProcessEntry32的指针,<br>&nbsp; // &nbsp;调用者应在释放List之前调用Dispose释放这些指针<br>var<br>&nbsp; snap:THandle;<br>&nbsp; lppe:TProcessEntry32;<br>&nbsp; P:PPROCESSENTRY32;<br>begin<br>&nbsp; snap:=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);<br>&nbsp; try<br>&nbsp; &nbsp; List.Clear;<br>&nbsp; &nbsp; FillChar(lppe,Sizeof(TProcessEntry32),0);<br>&nbsp; &nbsp; lppe.dwSize:=Sizeof(TProcessEntry32);<br>&nbsp; &nbsp; if Process32First(snap,lppe) then<br>&nbsp; &nbsp; &nbsp; repeat<br>&nbsp; &nbsp; &nbsp; &nbsp; if IDOnly then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List.AddObject(GetProcessExePath(lppe.th32ProcessID),Pointer(lppe.th32ProcessID))<br>&nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; New(P);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; P^:=lppe;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List.AddObject(lppe.szExeFile,Pointer(P));<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; until not Process32Next(snap,lppe);<br>&nbsp; finally<br>&nbsp; &nbsp; CloseHandle(snap);<br>&nbsp; end;<br>end;<br>
 
多人接受答案了。
 
后退
顶部