根据进程PID获取程序所在路径的函数 x32-x64 d7-d2007-xe2通用支持(Delphi全网首发)

  {获取进程路径}
  //此函数64位进程无效,需调用GetProcessImageFileName(32位64位全能)  
  GetModuleFileNameEx(pHandle, 0, Path, Length(Path));     

参考微软MSDN:

getProcessImageFileNameA 函数 (psapi.h) - Win32 apps | Microsoft Learn

主要用到的API:

GetProcessImageFileNameA 

GetLogicalDriveStrings

OpenProcess

QueryDosDevice

C++声明

DWORD GetProcessImageFileNameA(
  HANDLE hProcess,
  LPSTR  lpImageFileName,
  DWORD  nSize
);

  function GetProcessImageFileName(hProcess: Cardinal; lpImageFileName: LPSTR; nSize: DWORD): DWORD; stdcall;  external 'PSAPI.dll' name 'GetProcessImageFileNameA';


{根据进程PID获取程序所在路径的函数  x32-x64 d7-d2007-xe2通用支持}
function GetProcessExePath_x32_x64(PID: Cardinal): string;
var
  buf:array [0..MAX_PATH-1] of char;
  m_Result:Integer;
  i,j:Integer;
  str_temp:string;

  pHandle: Cardinal;
  DosPath:array[0..MAX_PATH-1] of AnsiChar;   //必须定义为 AnsiChar ,否则获取的数据在XE2会乱码
  sDosDrive:array[0..MAX_PATH-1] of Char;
  sDriveList:TStringList;
begin
  {获取驱动器列表}
  sDriveList:=TStringList.Create;
  m_Result:=GetLogicalDriveStrings(MAX_PATH,buf);
  for i:=0 to (m_Result div 4) do
  begin
    //str_temp:=string(buf[i*4]+buf[i*4+1]+buf[i*4+2]);    //C:\
    str_temp:=string(buf[i*4]+buf[i*4+1]);                 //C:
    sDriveList.Add(str_temp);
  end;

  {启用调试权限}
  //EnableDebugPriv;
  {获取进程句柄}
  pHandle := OpenProcess(PROCESS_QUERY_INFORMATION, False, PID);

  {获取进程路径}
  if GetProcessImageFileName(pHandle, DosPath, MAX_PATH+1) <>0 then  //该函数返回值为dospath长度,返回的第二个参数path数据为\Device\HarddiskVolume4\实用软件\DisplayX.exe这样的DOS路径。需转换
  begin
    for j:=0 to sDriveList.Count-1 do
    begin
      if QueryDosDevice(PChar(sDriveList.Strings[j]),sDosDrive ,MAX_PATH)<>0 then   //获取C:这样的NT盘符对应的\Device\HarddiskVolume1 这样的DOS路径
      begin
        if Pos(sDosDrive,DosPath)>0 then
        begin
          // Result:=sDriveList.Strings[j]+RightStr(DOSPath,Length(DOSPath)-StrLen(sDosDrive));   //WideString 长度用Length,PChar长度用StrLen,否则出错。
          Result:=sDriveList.Strings[j]+Copy(DOSPath,StrLen(sDosDrive)+1,Length(DOSPath)-StrLen(sDosDrive));  //delphi2007中使用此方法以免中文乱码
        end;
      end;
    end;
  end;
  sDriveList.Free;
  CloseHandle(pHandle);
  Form1.edit1.Text:=DosPath;
end;

效果如下图:

注:如不提升进程权限为DEBUG权限,则OpenProcess无法打开system用户级别进程,导致GetProcessImageFileName无法正常工作。

本代码为作者全网首发原创,非粘贴复制得来。转载请注明出处!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值