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版本,例如GetModuleFileNameExA
或GetModuleFileNameExW
?
如果您没有指定,我认为您默认调用ANSI版本。 由于C#字符串是Unicode,因此您看到的垃圾可能是将充满ANSI字符的缓冲区解释为Unicode字符串的结果。
有关此内容的更多信息,请参阅GetModuleFileNameEx函数上的Microsoft页面 。
虽然为了简洁起见,你可能会把它从你的片段中删除,但在这个特殊情况下它不会帮助你,正如David Heffernan指出的那样,你应该检查返回值。 🙂