我試圖訪問不同用戶的進程的圖像路徑。 (我試圖找出當前正在運行的進程是否已經由另一個用戶運行)。OpenProcess:ERROR_ACCESS_DENIED儘管PROCESS_QUERY_LIMITED_INFORMATION
從Vista開始,如果沒有UAC,.NET的System.Diagnostics.Process.MainModule
屬性將失敗。相反,Win32建議首先使用OpenProcess
與PROCESS_QUERY_LIMITED_INFORMATION
標誌來獲得句柄,然後QueryFullProcessImageName
。然而,除非這個過程是我自己的過程,否則就會失敗,或者我首先提升我的過程。撥打Marshal.GetLastWin32Error()
然後給我ERROR_ACCESS_DENIED
。
我的理解是'查詢有限信息'的整點是我不應該必須提升。
下面是我實現它:
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
[Flags]
public enum ProcessAccessFlags : uint
{
QueryLimitedInformation = 0x1000
}
[DllImport("kernel32.dll")]
private static extern bool QueryFullProcessImageName(IntPtr hprocess, int dwFlags,
StringBuilder lpExeName, out int size);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess,
bool bInheritHandle, int dwProcessId);
public static string GetMainModulePath(this Process process)
{
if (Environment.OSVersion.Version.Major < 6)
return process.MainModule.FileName;
var buffer = new StringBuilder(1024);
IntPtr hprocess = OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, process.Id);
if (hprocess != IntPtr.Zero)
{
try
{
int size = buffer.Capacity;
if (QueryFullProcessImageName(hprocess, 0, buffer, out size))
return buffer.ToString();
}
finally
{
CloseHandle(hprocess);
}
}
return string.Empty;
}
然後,我只是把它喜歡:
foreach (var item in Process.GetProcessesByName("chrome"))
{
item.GetMainModulePath();
}
這難道不是在所有的支持?
請注意,我*不*嘗試訪問系統進程。這些是簡單的用戶級GUI應用程序。 –