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

时间:2014-09-01 11:08:03

标签: c# wpf winapi

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

Delphi开发人员遇到类似的问题herehere。第一个问题是通过设置调试权限来解决的。不幸的是,似乎这对我没有帮助in 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计算机。

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

因此,您很可能会发现该功能失败。检查返回值,在这种情况下,值为零表示失败。如果失败,请使用Marshal.GetLastWin32Error获取错误代码。您的流程处理可能没有必要的访问权限。

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

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

答案 2 :(得分:-1)

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

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

有关详细信息,请参阅Microsoft's page on the GetModuleFileNameEx function

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