Windows 9x下可以用CreateToolhelp32Snapshot, Process32First, Process32Next获取进程的文件路径. 
    在NT内核系统下,上面三个函数只能得到进程名,得不到文件路径. 于是在NT下我用OpenProcess, EnumProcessModules, GetModuleFileNameEx获取文件路径. 但是现在有个问题,有些进程用OpenProcess打不开, 于是就取不到进程对应的文件路径了.
    有个进程管理程序 Process Explorer(Sysinternals公司创作的),所有进程除System与System Idle Process,都可以获得正确的文件路径. 还有一个疑点,我用CreateToolhelp32Snapshot, Process32First, Process32Next取得的进程名[System Process], 在任务管理器里却是 System Idle Process, 在第三方进程管理器Process Explorer里面也是 System Idle Process, 看来它们枚举进程的方法与我用的方法是不同的。
    请问在NT系统下,怎样实现不打开进程也能取得进程文件路径?

解决方案 »

  1.   

    一个示例函数,可以用在DLL中:
    ===========================function getExeName: string;
    var
      kk:array[0..MAX_PATH - 1] of char;
    begin
      windows.GetModuleFileName(System.MainInstance, kk, MAX_PATH);
      Result := kk;
    end;
      

  2.   

    标记一下: NT系统下怎样不打开进程也能取得进程文件路径?
    顺便问问: 哪位朋友有tdump.exe或dumpbin.exe的原代码,或者其他可以查看Exe/DLL信息的程序的原代码,请指点一下,可以另开帖给分.
      

  3.   

    budi(http://lysee.oicp.net): 
    要获取本进程的文件名也不用这么麻烦吧.
    Application.ExeName
      

  4.   

    http://msdn.microsoft.com/msdnmag/issues/02/07/CQA/
    OpenProcess is not needed
      

  5.   

    首先提高程序的运行级别到DEBUG
    function EnablePrivilege(hToken: Cardinal; PrivName: string; bEnable: Boolean): Boolean;
    var
    TP: TOKEN_PRIVILEGES;
    Dummy: Cardinal;
    begin
    TP.PrivilegeCount := 1;
    LookupPrivilegeValue(nil, pchar(PrivName), TP.Privileges[0].Luid);
    if bEnable then
    TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else TP.Privileges[0].Attributes := 0;
    AdjustTokenPrivileges(hToken, False, TP, SizeOf(TP), nil, Dummy);
    Result := GetLastError = ERROR_SUCCESS;
    end;var
    hToken: Cardinal;
    begin
      OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
      if not EnablePrivilege(hToken, 'SeDebugPrivilege', True) then Application.MessageBox('调试模式开启失败',nil);
      CloseHandle(hToken);
    end;
    ////////////////////////////////////
    //获得路径
    var
    h : THandle;
    fileName : string;
    iLen : integer;
    hMod : HMODULE;
    cbNeeded,hProcess : DWORD;
    begin
    hProcess=3458;  //进程PDI
       h := OpenProcess(PROCESS_ALL_ACCESS, false, hProcess);
       if h > 0 then
       begin
         if EnumProcessModules( h, @hMod, sizeof(hMod), cbNeeded) then
         begin
           SetLength(fileName, MAX_PATH);
           iLen := GetModuleFileNameEx(h, hMod, PCHAR(fileName), MAX_PATH);
           if iLen <> 0 then
           begin
             SetLength(fileName, StrLen(PCHAR(fileName)));
             showmessage(fileName); //获得的路径就在这了
           end;
         end;
       end;CloseHandle(h);
    end
      

  6.   

    谢谢 jiangsheng,我看过了,里面用 CProcessModuleIterator::GetProcessHandle取得进程的句柄,不用OpenProcess. 可是在DELPHI里面怎么用呢?微软的API里也没有 GetProcessHandle.
      

  7.   

    解决了。有这个权限就可以了。'SeDebugPrivilege'