如果你想摆脱Win32Exception并获得最佳性能,让我们这样做:
- 我们将使用Win32 API获取进程文件名
- 我们将实现一个缓存(仅解释)
首先,您需要导入Win32 API。
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
[DllImport("psapi.dll")]
static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In] [MarshalAs(UnmanagedType.U4)] int nSize);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
接下来,让我们编写一个返回处理文件名称的函数。
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string GetProcessName(int pid)
{
var processHandle = OpenProcess(0x0400 | 0x0010, false, pid);
if (processHandle == IntPtr.Zero)
{
return null;
}
const int lengthSb = 4000;
var sb = new StringBuilder(lengthSb);
string result = null;
if (GetModuleFileNameEx(processHandle, IntPtr.Zero, sb, lengthSb) > 0)
{
result = Path.GetFileName(sb.ToString());
}
CloseHandle(processHandle);
return result;
}
最后,让我们实现一个缓存,以便我们不必太频繁地调用此函数。创建一个名为 ProcessCacheItem 的类,其属性为(1)进程名称和(2)创建时间。添加常量 ItemLifetime 并设置为 60 秒。创建一个字典,其中键是进程 PID,值是 ProcessCacheItem 对象实例。当您想要获取进程名称时,请首先在缓存中检查。如果缓存项过期,则删除它并添加已刷新的项。