在我的WPF项目中,我通过GetModuleFileNameEx方法接收当前正在运行的进程的路径。它适用于大多数情况,但是例如当前正在运行的进程是“Windows资源管理器”(系统进程)时,我得到“C $Å”(以及其他随机字符)。
Delphi开发人员遇到类似的问题here和here。第一个问题是通过设置调试权限来解决的。不幸的是,似乎这对我没有帮助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计算机。
答案 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版本,例如GetModuleFileNameExA
或GetModuleFileNameExW
?
如果您没有指定,我认为您默认调用ANSI版本。由于C#字符串是Unicode,因此您看到的垃圾可能是将一个充满ANSI字符的缓冲区解释为Unicode字符串的结果。
有关详细信息,请参阅Microsoft's page on the GetModuleFileNameEx function。
虽然为了简洁起见,你可能会把它从你的片段中删除,但在这种特殊情况下它不会帮助你,正如David Heffernan指出的那样,你应该检查返回值。 : - )