Delphi获取EXE文件的句柄

4
下面是我现在的一个例子:
var
Client : String;
Handle : Integer;
begin
Client := 'Window Name';
GetWindowThreadProcessId(FindWindow(nil, PAnsiChar(Client)), @ProcessId);
Handle := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
end;

我更倾向于通过进程的exe名称来获取其句柄... 这个可能吗?

1
什么“句柄”?窗口句柄(HWND)、模块句柄(HMODULE)还是其他句柄? - Andreas Rejbrand
1
好的,所以你真正需要的句柄实际上是进程句柄,而不是窗口句柄。 - Andreas Rejbrand
1
你已经有什么可以用来获取进程句柄的东西了吗?如果你只有 EXE 名称,那么可能会有多个副本在运行,然后呢? - Eugene Mayevski 'Callback
1
如果您需要一个进程句柄,请调用EnumProcesses。 - David Heffernan
3
@Worm: 我很抱歉必须在这里同意Bryan的观点。实际上,你在这里的大多数评论(仅统计我看到的)都是同一类的,暗示诸如“天啊,这种无知杀死我了!”之类的东西。出于自己的利益考虑,即使没有其他原因,你也可能需要重新调整你的态度生成器。只是说一下... - Andreas Rejbrand
显示剩余25条评论
3个回答

5

由于vcldeveloper提供的链接已经失效,这里是完整的函数代码,可以在不使用第三方组件的情况下工作。

首先我们将找到进程ID(PID),然后通过打开所有访问权限获取进程句柄(因为OP在评论中提到他需要这个功能来进行ReadProcessMemory操作)。

如果PID函数返回0,则意味着该进程很可能未运行(或者只是未在正在运行的进程列表中找到)。

function GetPIDbyProcessName(processName:String):integer;
var 
  GotProcess: Boolean; 
  tempHandle: tHandle; 
  procE: tProcessEntry32;
begin
  tempHandle:=CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0); 
  procE.dwSize:=SizeOf(procE); 
  GotProcess:=Process32First(tempHandle, procE);
  {$B-} 
    if GotProcess and not SameText(procE.szExeFile, processName) then 
      repeat GotProcess := Process32Next(tempHandle, procE); 
      until (not GotProcess) or SameText(procE.szExeFile,processName); 
  {$B+}

  if GotProcess then 
    result := procE.th32ProcessID 
  else
    result := 0; // process not found in running process list

  CloseHandle(tempHandle);
end;

接下来,我们将从所得的进程 ID(PID)中获取/打开进程句柄。完整的代码/用法如下:
var myPID, myProcessHandle: integer;
begin
  myPID:=GetPIDbyProcessName('someExeName.exe');
  myProcessHandle:=OpenProcess(PROCESS_ALL_ACCESS,False,myPID);
end;

你需要以某种方式存储myProcessHandle,以便作为ReadProcessMemory(myProcessHandle...) 的第一个参数可访问。

此外,请将以下内容添加到全局使用子句中:
Winapi.Windows(用于ReadProcessMemory和OpenProcess)
Winapi.tlHelp32(用于获取PID tProcessEntry32变量)


4

Application.Handle是什么?
看起来你尝试在Delphi中使用WinAPI进行编程。在绝大多数情况下,不需要这样做,因为VCL提供了适当的面向对象包装。
也许你会在这个组件包中找到一些东西:GLibWMI


1
我有一种感觉,原帖作者并不是在寻找自己应用的句柄。 - Andreas Rejbrand
@Abelisto:安装了WinAPI帮助吗?MSDN有什么问题吗?http://msdn.microsoft.com/en-us/library/ms682629(v=vs.85).aspx - Andreas Rejbrand
@David 我不是在尝试,我已经做到了,sendkeys 只适用于大于>.>的赌注金额。 - Bryan
它为什么没有缩进?能解释一下吗?如果 Delphi 中有类似于自动换行的功能,可以让代码看起来更整洁,我会使用它的。 - Bryan
还有,对于刚开始学编程的人来说,喷他们有什么意义呢?这是我做的第一个重要项目之一,而且最后一次我工作的项目已经过去一年了。我之所以重新开始编程,只是因为我的一个朋友经常使用Delphi,希望我能重新开始编程,这样我们就可以一起合作做些东西。 - Bryan
显示剩余11条评论

3

您可以使用ProcessInfo

var
  ProcessInfo : TProcessInfo;
  Process : TProcessItem;
  PID: Cardinal;
  ProcessHandle : THandle;
begin
  ProcessInfo := TProcessInfo.Create(nil);
  try
    Process := ProcessInfo.RunningProcesses.FindByName('Notepad.exe');
    if Assigned(Process) then
    begin
      PID := Process.ProcessID;
      ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,False,PID);
      if ProcessHandle > 0 then
      try
        {Add your code here}
      finally
        CloseHandle(ProcessHandle);
      end;
  end;
  finally
    ProcessInfo.Free;
  end;
end;

如果您不喜欢使用第三方组件,您可以研究ProcessInfo的源代码,了解它如何检索正在运行的进程列表及其属性。基本上,它大多数功能都依赖于Windows Tool Help API。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接