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

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

参考微软MSDN:

https://docs.microsoft.com/zh-cn/windows/win32/api/psapi/nf-psapi-getprocessimagefilenamea

主要用到的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无法正常工作。

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

posted @   IT情深  阅读(168)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示