我正在开发一个应用程序,它应该能够显示和检索系统中所有进程的信息。
我尝试使用函数QueryFullProcessImageName获取进程的完整路径,但失败并显示错误31(连接到系统的设备不工作),这种情况仅发生在程序首次枚举运行进程后创建的新进程中。
下面是我用来获取完整路径的方法:
public static string GetProcessFullPath(SafeProcessHandle Handle)
{
uint MaxPathLength = 1024;
StringBuilder ExePath = new StringBuilder(1024);
if (NativeMethods.Win32ProcessFunctions.QueryFullProcessImageName(Handle.DangerousGetHandle(), 0, ExePath, ref MaxPathLength))
{
return ExePath.ToString();
}
else
{
Win32Exception ex = new Win32Exception(Marshal.GetLastWin32Error());
Logger.WriteEntry(new LogEntry("Non è stato possibile recuperare il percorso completo dell'eseguibile di un processo, codice di errore: " + ex.NativeErrorCode + " (" + ex.Message + ")", EventSource.WindowsAPI, EventSeverity.Error));
return "Non disponibile";
}
}
下面是函数的声明:
[DllImport("Kernel32.dll", EntryPoint = "QueryFullProcessImageNameW", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool QueryFullProcessImageName(IntPtr ProcessHandle, uint PathType, StringBuilder ExePath, ref uint Characters);
我不知道导致此错误的原因,我从WMI(Win32_ProcessStartTrace)收到新进程的通知。
这就是我获取GetProcessFullPath方法中使用的进程句柄的方式(PID来自WMI通知):
public static SafeProcessHandle GetProcessHandle(uint ProcessID)
{
IntPtr UnsafeProcessHandle = NativeMethods.Win32ProcessFunctions.OpenProcess(NativeMethods.Win32Enumerations.ProcessAccessRights.PROCESS_ALL_ACCESS, false, ProcessID);
if (UnsafeProcessHandle == IntPtr.Zero)
{
UnsafeProcessHandle = NativeMethods.Win32ProcessFunctions.OpenProcess(NativeMethods.Win32Enumerations.ProcessAccessRights.PROCESS_QUERY_LIMITED_INFORMATION, false, ProcessID);
if (UnsafeProcessHandle == IntPtr.Zero)
{
Win32Exception ex = new Win32Exception(Marshal.GetLastWin32Error());
Logger.WriteEntry(new LogEntry("Non è stato possibile aprire un processo, codice di errore: " + ex.NativeErrorCode + " (" + ex.Message + ")", EventSource.WindowsAPI, EventSeverity.Error));
return new SafeProcessHandle(UnsafeProcessHandle, true);
}
else
{
return new SafeProcessHandle(UnsafeProcessHandle, true);
}
}
else
{
return new SafeProcessHandle(UnsafeProcessHandle, true);
}
}
编辑:进一步的测试表明,即使我试图获取其完整路径的进程在调用函数时已经启动,也会发生问题。
2条答案
按热度按时间lh80um4z1#
GetProcessImageFileName
可以工作,但它以设备形式返回路径,而我需要Win32路径。您可以使用GetLogicalDriveStrings和QueryDosDevice将dos文件路径转换为windows文件路径。
一些代码:
然后简单地呼叫,
您可以将其转换为C#代码。
huus2vyu2#
QueryFullProcessImageName
函数因ERROR_GEN_FAILURE
而失败(31
或0x1f
,“A device attached to the system is not functioning”)如果进程是“僵尸”进程,即进程已终止但并非所有句柄都已关闭。在这种情况下,您仍然可以使用带有PROCESS_NAME_NATIVE
标志的QueryFullProcessImageNameW
来获取本机路径,但您可能只想跳过它,因为它不再运行了。