GetModuleFileNameEx函数返回错误的系统进程路径

在我的WPF项目中,我通过GetModuleFileNameEx方法接收当前正在运行的进程的路径。 它适用于大多数情况,但是例如当当前运行的进程是“Windows资源管理器”( 系统进程 )时,我得到“C $Å”(以及其他随机字符)。

Delphi开发人员在这里和这里都有类似的问题。 第一个问题是通过设置调试权限来解决的。 不幸的是,看来,这对C#没有帮助…

这是方法:

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

在这里我称之为方法:

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

有没有人面临类似的问题或有想法如何解决这个问题? 谢谢。

顺便说一句,我正在运行Windows 8.1,64bit机器。

您可以使用System.Diagnostics.Process类。 假设您拥有可以使用的流程的ID

 var process = Process.GetProcessById(processId); var fileName = process.MainModule.FileName; 

您没有检查GetModuleFileNameEx的返回值是否有错误。

所以,很可能你会发现这个function失败了。 检查返回值,在这种情况下,值为零表示失败。 如果失败,请使用Marshal.GetLastWin32Error获取错误代码。 可能您的进程句柄没有必要的访问权限。

你也可以调用该函数的Unicode版本。

最后, Process.MainModule.FileName是获取此信息的一种更简单的方法。

您是否正在调用GetModuleFileNameEx的ANSI或Unicode版本,例如GetModuleFileNameExAGetModuleFileNameExW

如果您没有指定,我认为您默认调用ANSI版本。 由于C#字符串是Unicode,因此您看到的垃圾可能是将充满ANSI字符的缓冲区解释为Unicode字符串的结果。

有关此内容的更多信息,请参阅GetModuleFileNameEx函数上的Microsoft页面 。

虽然为了简洁起见,你可能会把它从你的片段中删除,但在这个特殊情况下它不会帮助你,正如David Heffernan指出的那样,你应该检查返回值。 🙂