DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: 33227
今日帖子: 12
在线用户: 22
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/8 21:03:35
标题:
通过进程名获取该进程的完整路径的问题~ 浏览:2437
加入我的收藏
楼主: delphi XE 10.2.3,用下面的函数: 
【调用是: ShowMessage(GetPathFileofModule('explorer.exe'));  
 要uses TlHelp32,psapi;】在32位系统下可以获取到路径,但是在64位系统下就不行了。寻大神指点~~~~

function GetPathFileofModule(ModuleName:String):String; //枚举进程文件所在路径
var
 hProcSnap: THandle;
 pProcess: THandle;
 pe32: TProcessEntry32;
 buf:array[0..MAX_PATH] of char; 
 hMod:HMODULE;
 cbNeeded:DWORD;
begin
hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);
 if hProcSnap = INVALID_HANDLE_VALUE then Exit;
 pe32.dwSize := SizeOf(ProcessEntry32);
 if Process32First(hProcSnap, pe32) = True then
 while Process32Next(hProcSnap, pe32) = True do
  begin
   if uppercase(pe32.szExeFile)=uppercase(ModuleName) then
    begin
     pProcess:=OpenProcess(PROCESS_QUERY_INFORMATION or
     PROCESS_VM_READ,
    FALSE,
   pe32.th32ProcessID);
 if pProcess<>0 then
 begin 
 if EnumProcessModules( pProcess,@hMod,sizeof(hMod),cbNeeded) then
   begin
    ZeroMemory(@buf,MAX_PATH+1);
    GetModuleFileNameEx(pProcess, hMod,buf,MAX_PATH+1);
    Result:=strpas(buf);
end;
end;
end;
end;
CloseHandle(hProcSnap);
end;
----------------------------------------------
-
作者:
男 tuesdays (Tuesday) ▲▲▲▲△ -
普通会员
2018/10/8 21:54:30
1楼: win下, 不能用这个方式. 特别在win7有时仅读到程序exe名.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/8 21:59:57
2楼: 32位的系统没问题,64位显示是空的,请教高手应该怎么解决?
----------------------------------------------
-
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/8 22:18:44
3楼: 查网上资料发现,可以用QueryFullProcessImageName 这个函数,最低要求VISTA系统,XP太老了,这个函数可以用! 但是不知道怎么利用~
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/10/8 23:11:20
4楼: function GetProgramFileNameByProcessName(ProcessName: string; var FileName: string): Boolean;
var
  lsFound: Boolean;
  AHandle: THandle;
  ProcessEntry32: TProcessEntry32;
  APath: string;
begin
  Result := False;
  FileName := '';
  AHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  try
    ProcessEntry32.dwSize := Sizeof(ProcessEntry32);
    lsFound := Process32First(AHandle, ProcessEntry32);
    while lsFound do
    begin
      GetProgramFileNameByProcessID(ProcessEntry32.th32ProcessID, APath);
      if (UpperCase(ExtractFileName(APath)) = UpperCase(ProcessName)) or
        (UpperCase(APath) = UpperCase(ProcessName)) then
      begin
        FileName := APath;
        Result := True;
        break;
      end;
      lsFound := Process32Next(AHandle, ProcessEntry32);
    end;
  finally
    CloseHandle(AHandle);
  end;
end;

win7 64 没有问题
明天看看 win10 64。




function GetProgramFileNameByProcessName(ProcessName: string; var FileName: string; SessionIDToCheck: DWORD = $FFFFFFFF): Boolean;
var
  lsFound: Boolean;
  AHandle: THandle;
  ProcessEntry32: TProcessEntry32;
  APath: string;
begin
  Result := False;
  FileName := '';
  AHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  try
    ProcessEntry32.dwSize := Sizeof(ProcessEntry32);
    lsFound := Process32First(AHandle, ProcessEntry32);
    while lsFound do
    begin
      GetProgramFileNameByProcessID(ProcessEntry32.th32ProcessID, APath);
      if (UpperCase(ExtractFileName(APath)) = UpperCase(ProcessName)) or
        (UpperCase(APath) = UpperCase(ProcessName)) then
      begin
        if CheckSessionID(ProcessEntry32, SessionIDToCheck) then
        begin
          FileName := APath;
          Result := True;
          break;
        end;
      end;
      lsFound := Process32Next(AHandle, ProcessEntry32);
    end;
  finally
    CloseHandle(AHandle);
  end;
end;
这个是 多一个无意义的判断版本。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/8 23:30:45
4楼: function NazwaProcesu(const uchwyt: Thandle): string;
type
  TQueryFullProcessImageName = function(hProcess: Thandle; dwFlags: DWORD; lpExeName: PChar; nSize: PDWORD): BOOL; stdcall;
var
  pid: DWORD;
  hProcess: Thandle;
  sciezka: array [0 .. MAX_PATH - 1] of Char;
  QueryFullProcessImageName: TQueryFullProcessImageName;
  nSize: cardinal;
begin
  Result := '';
  GetWindowThreadProcessId(uchwyt, pid);
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, pid);
  if hProcess <> 0 then
    try
      if GetModuleFileNameEX(hProcess, 0, sciezka, MAX_PATH) <> 0 then Result := sciezka
      else if Win32MajorVersion >= 6 then
      begin
        nSize := MAX_PATH;
        ZeroMemory(@sciezka, MAX_PATH);
        @QueryFullProcessImageName := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
        if Assigned(QueryFullProcessImageName) then
          if QueryFullProcessImageName(hProcess, 0, sciezka, @nSize) then Result := sciezka
      end;
    finally
      CloseHandle(hProcess);
    end;
end;

网上找的一段代码,不知道 怎么调用,比如说知道有个进程 explorer.exe 怎么调用这个函数呢? 大神指点一下~
----------------------------------------------
-
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/8 23:31:51
5楼: @wang_80919 高手出招。一会儿试试。~~
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/10/8 23:40:42
6楼: ProcessEntry32.th32ProcessID 就是 pid 。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/9 0:08:44
7楼: GetProgramFileNameByProcessID 提示这个 undeclared identifier...
是还差一段代码吗?
调用的话是不是: GetProgramFileNameByProcessName('explorer.exe'); 这样子的?
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/10/9 1:06:03
8楼: getmodulefilenameex没问题。关键看你openprocess的时候用的什么权限。

没有delphi,用c写了个,你可以参考一下。

template<typename ENUM_PROCESS_ROUTINE, typename ENUM_PROCESS_ROUTINE_PARAMETER>
int EmunProcess(ENUM_PROCESS_ROUTINE pRoutine, ENUM_PROCESS_ROUTINE_PARAMETER pParameter)
{
  int nReturn = 0;

  DWORD dwProcesses[1024], cbNeeded;

  if (!EnumProcesses(dwProcesses, sizeof(dwProcesses), &cbNeeded))
    return 0;

  DWORD dwCount = cbNeeded / sizeof(cbNeeded);
  DWORD dwIndex = 0;
  LPTSTR szProcessName = (LPTSTR)malloc(0x10000 * sizeof(szProcessName));
  if (NULL == szProcessName)
    return 0;

  for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
  {
    if (0 == dwProcesses[dwIndex])
      continue;

    /// Get a handle to the process.
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcesses[dwIndex]);

    /// Get the process name.
    if (NULL == hProcess)
      continue;


    HMODULE hModule;
    if (!EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded))
    {
      CloseHandle(hProcess);
      continue;
    }

    if (GetModuleFileNameEx(hProcess, hModule, szProcessName, 0x10000) == 0)
    {
      CloseHandle(hProcess);
      continue;
    }

    if (NULL != &pRoutine)
    {
      if (!pRoutine(hProcess, szProcessName, pParameter))
      {
        CloseHandle(hProcess);
        break;
      }
    }

    CloseHandle(hProcess);
    nReturn++;
  }
  free((void *)szProcessName);

  return nReturn;
}


调用:

  EmunProcess(
    [](HANDLE hProcess, LPCTSTR pszProcessName, int)
    {
      printf("%ls\n", pszProcessName);
      return true;
    },
    0);
  system("pause");
  return 0;
----------------------------------------------
--
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/10/9 8:53:06
9楼: function GetProgramFileNameByProcessID(ProcessID: ULONG; var FileName: string; RaiseOSError: Boolean = False): Boolean;
var
  FHandle: THandle;
  VBufSize: DWORD;
begin
  Result := False;
  FileName := '';
  FHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
  VBufSize := MAX_PATH * MAX_PATH;
  SetLength(FileName, VBufSize);
  if TOSVersion.Check(6) then
  begin
    if (not QueryFullProcessImageName(FHandle, 0, PChar(FileName), VBufSize)) and RaiseOSError then
    begin
      RaiseLastOSError;
      exit;
    end;
  end
  else
  begin
    if TOSVersion.Check(5, 1) then
    begin
       VBufSize := GetModuleFileNameEx(FHandle, 0, PChar(FileName), VBufSize);
fSize);
    end
    else
    begin
      VBufSize := GetModuleFileName(FHandle, PChar(FileName), VBufSize);
    end;
    if (VBufSize = 0) and RaiseOSError then
    begin
      RaiseLastOSError;
      exit;
    end;
  end;
  SetLength(FileName, VBufSize);
  FileName := FileName.Trim;
  Result := True;
end;

结合 4 楼 的第一个函数。

QueryFullProcessImageName 函数定义。

function QueryFullProcessImageNameA(hProcess: THandle; dwFlags: DWORD; lpExeName: LPSTR;
  var nSize: DWORD): BOOL; stdcall; external kernelbase name 'QueryFullProcessImageNameA' delayed;
{$EXTERNALSYM QueryFullProcessImageNameA}
function QueryFullProcessImageNameW(hProcess: THandle; dwFlags: DWORD; lpExeName: LPWSTR;
  var nSize: DWORD): BOOL; stdcall; external kernelbase name 'QueryFullProcessImageNameW' delayed;
{$EXTERNALSYM QueryFullProcessImageNameW}
function QueryFullProcessImageName(hProcess: THandle; dwFlags: DWORD; lpExeName: LPTSTR;
  var nSize: DWORD): BOOL; stdcall; external kernelbase name 'QueryFullProcessImageNameW' delayed;
{$EXTERNALSYM QueryFullProcessImageName}
----------------------------------------------
(C)(P)Flying Wang
作者:
男 hs_kill (lzl_17948876) ★☆☆☆☆ -
普通会员
2018/10/9 9:45:06
10楼: win7/win10 64完全正常, 不需要管理员权限


uses
    Winapi.TlHelp32, Winapi.PsAPI;


var
  nContinueLoop: BOOL;
  nSnapShotHandle: THandle;
  nProcessEntry32: TProcessEntry32;
  nPrHandle: Cardinal;
  nMBF: array [0..MAX_PATH] of WideChar;
  nFileName: string;
  nSize: Cardinal;
begin
  try
    Memo1.Lines.Clear;
    nSnapShotHandle := CreateToolhelp32SnapShot(TH32CS_SNAPPROCESS, 0);
    try
      nProcessEntry32.dwSize := SizeOf(nProcessEntry32);
      nContinueLoop := Process32First(nSnapShotHandle, nProcessEntry32);
      while nContinueLoop do
      try
        nPrHandle := OpenProcess(PROCESS_ALL_ACCESS, False, nProcessEntry32.th32ProcessID);
        if nPrHandle = 0 then
          Continue;

        try
          nSize := GetModuleFileNameExW(nPrHandle, 0, @nMBF[0], SizeOf(nMBF));
          nMBF[nSize] := #0;
          nFileName := WideString(nMBF);
          Memo1.Lines.Add(nFileName);
        finally
          CloseHandle(nPrHandle);
        end;
      finally
        nContinueLoop := Process32Next(nSnapShotHandle, nProcessEntry32);
      end;
    finally
      CloseHandle(nSnapShotHandle);
    end;
  except
  end;
end;
----------------------------------------------
http://www.cnblogs.com/lzl_17948876/
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/17 14:18:46
11楼: @ hs_kill 谢谢这位大哥,你的代码我测试了,只能显示出32位程序的完整路径,64位的不行。
----------------------------------------------
-
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/17 14:20:37
12楼: @ bahamut8348 这位大哥也感谢你。不过小弟是DELPHI新手,C代码就只有眼瞎了。才接触这个,自学才2天。
----------------------------------------------
-
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/17 14:30:17
13楼: @ wang_80919 大大的代码测试好像有BUG,不知道怎么调用。
应该是GetProgramFileNameByProcessName 这一个~!
GetProgramFileNameByProcessName('explorer.exe'); 这样调用提示缺少参数。
因为我在任务管理器里只能看到一个进程名,如: qq.exe calc.xe 这类的。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/10/17 16:05:03
14楼: 你不会调用,就说老子写的代码有 BUG?
我看是你脑子有 BUG 吧。

函数代码都写给你了,你 TMD 眼瞎看不见几个参数吗?
----------------------------------------------
(C)(P)Flying Wang
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/17 17:35:52
14楼: 下午自己研究学习了一下,流程是通过进程名获取到进程的ID,再通过ID获取到句柄,再得到完整的路径。代码如下,大神过目看看有没有什么地方不严谨。

type 下增加:
function QueryFullProcessImageNameW(Process: THandle; Flags: DWORD; Buffer: PChar;
  Size: PDWORD): Boolean; stdcall; external 'kernel32.dll'; 

uses psapi,TLhelp32;

Function GetPID(ProcessName:String):String;
var
     h:thandle;
     f:boolean;
     lppe:tprocessentry32;
begin
     h := CreateToolhelp32Snapshot(TH32cs_SnapProcess, 0);
     lppe.dwSize := sizeof(lppe);
     f := Process32First(h, lppe);
     while integer(f) <> 0 do
     begin
       if lppe.szExeFile = ProcessName then
       begin
         Result:=(inttostr(lppe.th32ProcessID));
         break;
       end;
       f := Process32Next(h, lppe);
     end;
end;

function GetProcessExeFullPath(PID: Cardinal): string;
const
  PROCESS_QUERY_LIMITED_INFORMATION = $1000;
  var
pHandle: THandle;
buf: array[0..MAX_PATH-1] of Char;
STR_SIZE    : DWORD;

begin
// pHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
// 用以上权限不能获取SYSTEM进程的路径
 pHandle := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PID);
 STR_SIZE := Length(Buf);
 QueryFullProcessImageNameW(pHandle, 0, @buf, @STR_SIZE);
 CloseHandle(pHandle);
 Result := buf;
end;

调用:
showmessage(GetProcessExeFullPath(strtoint(GetPID('explorer.exe'))));

像我这种菜鸟级别的可以看懂了,以上大神们写的代码,还不懂怎么调用!还要进一步学习才行~
----------------------------------------------
-
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/17 17:43:17
15楼: @ wang_80919 大大,你的代码的确有问题!因为编译通不过。 我上图:
火气别这么大嘛,我本来就是菜鸟,DELPHI的书都没看,自己慢慢实践学习,你是大神,就别跟我们这种菜鸟计较了嘛。不耻下问。
此帖子包含附件:
PNG 图像
大小:2,349B
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/10/17 19:00:28
16楼: 一开始说 缺少参数。
又 TMD 说编译不通过。

不过呢,很正常,旧版 DELPHI 多半是不通过的。
太旧的,肯定是不通过的。

不过 你 IDE 提示都 TMD 不给截图,你是保密局的吗?

而且,我猜,你不是因为 IDE 太旧,而是因为你脑子有病。

不看书,还这么理直气壮的,肯定是脑子有病。

你不耻下问,我不管。
但是,我因为,我曾经 回答了你的问题,而感到羞耻。

希望 我发的代码,能给别人看到,这样至少不是做了 无用功。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 psstudio (天下) ★☆☆☆☆ -
普通会员
2018/10/17 19:38:12
17楼: @ 我是delphi XE 10.2.3 编译那个就没截图了。。上面那个 fSize); 
这里单一行就是这个编译不通过。
有用的,大哥,就是在你的代码启发下我自己再改的。。你就不要和我这种初学又不看书,还脑子有病的人斤斤计较了嘛。。嘿嘿。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/10/17 19:44:42
18楼: 老子在这个帖子里就没写过 fSize 这个单词。
老子写的是 VBufSize。而且这个单词不影响编译。

反正,你都没图,你说啥就是啥吧。
----------------------------------------------
(C)(P)Flying Wang
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行97.65625毫秒 RSS