0

In my WPF project, I am receiving the path of the currently running process via the GetModuleFileNameEx method. It works in most cases, but for example when the currently running process is "Windows Explorer" (a system process), I get "C$Å" (and other random characters).

Delphi developers had a similar problem here and here. The first problem was solved by setting a debug privilege. Unfortunately, It seems, this doesn't help me in C#...

This is the method:

[DllImport("psapi.dll", SetLastError = true)]
private static extern int GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, StringBuilder lpFilename, int nSize);

Here I call the method:

// Get module file name
var buffer = new StringBuilder(4096);
GetModuleFileNameEx(hProcess, IntPtr.Zero, buffer, buffer.Capacity);
process = buffer.ToString();

Did anyone face similar problems or has an idea how to solve this issue? Thanks.

Btw, I am running a Windows 8.1, 64bit machine.

Community
  • 1
  • 1
casaout
  • 1,819
  • 3
  • 24
  • 54
  • 1
    Have you looked at `System.Diagnostics.Process` (particularly `MainModule.FileName`)? Or is there a reason you don't use that class? – Dirk Sep 01 '14 at 11:14
  • hi Dirk. Thanks a lot for your suggestion. Actually, I just found out that I can use the processId to get the name of the process (program) with `Process.GetProcessById(processId).ProcessName`. Didn't know that existed. Thanks for pointing me out to other opportunities ;) PS: If you add comment as an answer, I could accept it! – casaout Sep 01 '14 at 11:32

3 Answers3

2

You can use the System.Diagnostics.Process class for that. Assuming you have the ID of a process you can use

var process = Process.GetProcessById(processId);
var fileName = process.MainModule.FileName;
Dirk
  • 10,668
  • 2
  • 35
  • 49
  • 1
    It is bad approach to use build-in methods just because they are "simpler" –  Jul 03 '17 at 15:17
  • 2
    @AlekDepler In what sense is this a bad approach if .NET is already a dependency? – Eric Eskildsen Jul 09 '17 at 11:49
  • In that sense that it very restricted functionality, for example you cannot get filename of 64bit process within 32bit process. And while developing commercial product you cannot change process bitness just to fix this issue - so this restricted, bitness-dependent solution which will work only in certain cases –  Jul 10 '17 at 10:04
  • @Eric It seems that Alek is a bit grumpy that the perfectly reasonable answers to this question don't solve his different problem. – David Heffernan Jul 11 '17 at 09:25
1

You are not checking the return value of GetModuleFileNameEx for errors.

So, most likely you'll find that the function is failing. Check the return value, in this case a value of zero indicates failure. In case of failure use Marshal.GetLastWin32Error to obtain the error code. Likely your process handle doesn't have the necessary access rights.

You would also do well to call the Unicode version of the function.

Finally, Process.MainModule.FileName is a much simpler way to get this information.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • @AlekDepler This was an answer to the question, and I believe it is accurate. Perhaps you aren't familiar with how to check for errors on Win32. But this answer explains why the call to `GetModuleFileNameEx` appeared to return gibberish. How to deal with that and perform proper error checking. Remember that this is an answer to this question, not an attempt to solve your problem. Your problem is that your code runs in the 32 bit WOW64 emulator and you are asking for information about a 64 bit process. Quite different from this topic. – David Heffernan Jul 11 '17 at 09:28
  • @DavidHeffernan forget it, I'm able to get x64 process info within x32 using WinApi. I just dont like people posting the most simple solution ever and defending their point no matter what restrictions it assumes –  Jul 11 '17 at 13:11
  • @AlekDepler I think you are confused between your problem and its solution, and the question asked here. The question asked here was why `GetModuleFileNameEx` failed. If you think it's an omission not to mention issues getting 64 module names from a 32 bit process, then you clearly don't understand how Stack Overflow works. We answer the questions that are asked. – David Heffernan Jul 11 '17 at 13:13
  • @DavidHeffernan, I clearly understand how stack overflow works now - it's like a huge garbage collection which provides you mostly simpliest and because of that inefficient "solutions" –  Jul 11 '17 at 13:20
  • @Alek Depler - Entitled much? Sorry our answers aren't up to your high standards. Looking at your activity, I see that the few answers you've provided aren't well regarded, and your comments usually have the same bitchy tone as above. Did you know that a big part of being a good coder/developer/engineer is working well with others? – Scott Smith Jul 15 '17 at 19:06
  • I was talking to you – David Heffernan Jul 16 '17 at 19:19
-1

Are you calling the ANSI or Unicode version of GetModuleFileNameEx, e.g. GetModuleFileNameExA or GetModuleFileNameExW?

If you don't specify, I think you're calling the ANSI version by default. Since C# strings are Unicode, the garbage you're seeing may be the result of interpreting a buffer full of ANSI characters as a Unicode string.

For more information on this, see Microsoft's page on the GetModuleFileNameEx function.

Though you probably left it out of your snippet for the sake of brevity, and it wouldn't have helped you in this particular case, as David Heffernan pointed out, you should be checking the return value. :-)

Community
  • 1
  • 1
Scott Smith
  • 3,900
  • 2
  • 31
  • 63