1

I am trying to get the path from running processes in Windows 10 without success. Here is the code I am using:

procedure GetPathFromProcessList(List: TStringList);
var
  Shot: THandle;
  Proc: THandle;
  Data: TProcessEntry32;
  Path: array[0..MAX_PATH - 1] of Char;
begin
  Shot := CreateToolHelp32Snapshot(TH32CS_SNAPALL, 0); //TH32CS_SNAPPROCESS
  if (Shot <> 0) then
  try
    List.Sorted := True;
    List.Duplicates := dupIgnore;
    List.BeginUpdate;
    if (Process32First(Shot, Data)) then
    repeat
      // PROCESS_QUERY_LIMITED_INFORMATION = $1000
      Proc := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, Data.th32ProcessID);
      if (Proc <> 0) then
      try
        if (GetModuleFileNameEx(Proc, 0, Path, MAX_PATH) <> 0) then
            List.Add(LowerCase(Path));
      finally
        CloseHandle(Proc);
      end;
    until (not Process32Next(Shot, Data));
    List.EndUpdate;
  finally
    CloseHandle(Shot);
  end;
end;

My application asks for elevated privileges and I already tried to use PROCESS_QUERY_LIMITED_INFORMATION ($1000) in OpenProcess, but the problem is the same.

It doesn't give me any error, but list is empty in Windows 10. In Windows 7 it works without problem...

Please, anyone knows what is going on? Thank you!

Guybrush
  • 1,575
  • 2
  • 27
  • 51
  • TH32CS_SNAPMODULE32 includes 32bit processed on a 64bit system – FredS Nov 28 '16 at 17:57
  • @FredS, this function worked in a Windows 7 64 bit, but not in a Windows 10 32 bit... – Guybrush Nov 28 '16 at 18:04
  • 4
    It doesn't give you any errors because you're not *reporting* any errors. When an API function fails, do what the documentation tells you to discover what the problem was. (That often means calling `GetLastError`. Check the documentation to be sure.) – Rob Kennedy Nov 28 '16 at 18:32
  • @RobKennedy, I added "if (Proc <> 0) then begin ... end else List.Add(SysErrorMessage(GetLastError));" ... in Windows 7 I got some lines from list with errors like Access Denied and Incorrect Parameter, but in Windows 10 the list is still empty... – Guybrush Nov 28 '16 at 19:03
  • 1
    Where does your program go wrong? Use the debugger to find out. – Rob Kennedy Nov 28 '16 at 19:06
  • Problem is I am using Delphi 7, and once I run it directly from IDE, when app invokes higher privileges from Windows, Delphi 7 freezes and I need to reestart Windows... – Guybrush Nov 28 '16 at 19:16
  • OK. Then use *other* methods to find out. Or skip elevating privileges. Also, there are *five* API calls of interest here. Are you checking for errors from *all* of them? – Rob Kennedy Nov 28 '16 at 19:39
  • If you run the IDE elevated (not recommended normally), the process it spawns (your app) will run elevated. – Sertac Akyuz Nov 28 '16 at 20:23
  • @RobKennedy, for using the debug from Delphi I would need to install it in Windows 10. What other methods can I use?... I already checked errors in every API calls, but I do not know why in Windows 10 I get no errors... – Guybrush Nov 28 '16 at 20:25
  • You could use logging. – Rob Kennedy Nov 28 '16 at 20:28
  • Learn about trace debugging. – David Heffernan Nov 28 '16 at 21:26
  • 2
    Using your code and adding `RaiseLastOSError`'s as already been suggested by others, I get an error on Process32First. You are not [setting the size member](http://stackoverflow.com/a/14492379/52598) of `Data`. Setting the size member solves at least that. – Lieven Keersmaekers Nov 29 '16 at 05:59
  • and fwiw, you should add `RaiseLastOSError` *(or GetLastError and act as you like)* to check the results of `Process32First`, `OpenProcess` and `GetModuleFileNameEx` *(as Rob already told you in comments)* – Lieven Keersmaekers Nov 29 '16 at 06:12
  • As first I would move `List.EndUpdate;` into the `finally` block. If you do not do it and an exception happens you will get a filled list but only a empty list **can visually be seen**. – moskito-x Nov 29 '16 at 07:17
  • Ok, thank you all for the comments! I will do more tests. – Guybrush Nov 29 '16 at 12:07
  • @LievenKeersmaekers, you are right. Setting the size of Data before calling Process32First solved the problem! Please, add your solution so I can accept it. Thank you! – Guybrush Nov 29 '16 at 12:31
  • Appreciated but it wouldn't be correct. Adding errorhandling had already been suggested. Once the error was clear, it just took a search on that message to find a solution. If there's anything to be learned from this, it's @RobKennedy 's comment about reporting errors. – Lieven Keersmaekers Nov 29 '16 at 13:46
  • Ok, let's wait @RobKennedy than... – Guybrush Nov 29 '16 at 13:56
  • What are you waiting for me for? I voted to close this question yesterday. It has nothing to do with getting the process path, nor with Windows 10. If you had responded to my first comment by *actually* checking all the errors, or to my second by *actually* determining which API function failed, you'd have been able to resolve this problem yourself. Instead, you lazily waited for someone else to run your code for you. If you want to [edit] your question to pretend you *did* do as I suggested, and then just ask what `Process32First`'s error code means, then do so, and then Lieven can answer it. – Rob Kennedy Nov 29 '16 at 14:09
  • @RobKennedy, I am not lazy, I acctually did a LOT of tests. If I had all your knoledge about this I would solved the problem myself, for sure... Thank you anyway... – Guybrush Nov 29 '16 at 16:03

1 Answers1

0

If you follow the MSDN documentation it tells you that you need to initialize the dwSize member variable of the PROCESSENTRY and MODULEENTRY structures.

You can do so easily:

moduleEntry32.dwSize = sizeof(MODULEENTRY32);

This will solve your problem

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59