获取所有应用程序的列表

我正在尝试获取所有打开的应用程序的列表。 具体来说,如果您打开任务管理器并转到应用程序选项卡,该列表。

我试过用这样的东西:

foreach (var p in Process.GetProcesses()) { try { if (!String.IsNullOrEmpty(p.MainWindowTitle)) { sb.Append("\r\n"); sb.Append("Window title: " + p.MainWindowTitle.ToString()); sb.Append("\r\n"); } } catch { } } 

就像我发现的一些例子一样,但这并没有为我提供所有的应用程序。 它只抓住了我在任务管理器中看到的一半,或者我知道我已经打开了。 例如,由于某种原因,此方法不会选择Notepad ++或Skype,但是它会选择谷歌浏览器,计算器和Microsoft Word。

有谁知道为什么这不正常或怎么做?

此外,一位朋友建议它可能是一个权限问题,但我以管理员身份运行visual studio,但它没有改变。

编辑:我得到的问题是,我给出的大多数解决方案只返回一个所有进程的列表,这不是我想要的。 我只想要打开的应用程序或窗口,就像任务管理器上显示的列表一样。 不是每个进程的列表。

另外,我知道这里有不好的代码,包括空的catch块。 这是一个一次性项目,只是为了弄清楚这是如何起作用的。

这里的代码示例似乎给出了您的要求。 修改版:

 public class DesktopWindow { public IntPtr Handle { get; set; } public string Title { get; set; } public bool IsVisible { get; set; } } public class User32Helper { public delegate bool EnumDelegate(IntPtr hWnd, int lParam); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount); [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)] public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam); public static List GetDesktopWindows() { var collection = new List(); EnumDelegate filter = delegate(IntPtr hWnd, int lParam) { var result = new StringBuilder(255); GetWindowText(hWnd, result, result.Capacity + 1); string title = result.ToString(); var isVisible = !string.IsNullOrEmpty(title) && IsWindowVisible(hWnd); collection.Add(new DesktopWindow { Handle = hWnd, Title = title, IsVisible = isVisible }); return true; }; EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero); return collection; } } 

使用上面的代码,调用User32Helper.GetDesktopWindows()应该为您提供一个列表,其中包含所有打开的应用程序的句柄/标题以及它们是否可见。 请注意,无论窗口的可见性如何,都会返回true ,因为该项仍将显示在作者要求的“任务管理器”的“应用程序”列表中。

然后,您可以使用集合中某个项的相应Handle属性,使用其他窗口函数 (如ShowWindow或EndTask )执行许多其他任务。

正如马修注意到的那样,可能是因为他们没有主要头衔,因此你将其过滤掉了。 以下代码将运行所有进程。 然后,您可以使用Process.ProcessName过滤掉您不想要的那个。 以下是使用ProcessName的文档。

 using System.Diagnostics; Process[] processes = Process.GetProcesses(); foreach (Process process in processes) { //Get whatever attribute for process } 

我认为,由于某些原因,MainWindowTitle对于某些进程为null,因此您正在跳过这些进程。 试试这个只是为了测试:

 foreach (var p in Process.GetProcesses()) { sb.Append("\r\n"); sb.Append("Process Name: " + p.ProcessName); sb.Append("\r\n"); } 

也许你的尝试… catch会跳过一些进程,如果它有一些错误,所以尝试没有它也。

更新:尝试这个,它很难看,并采取一些没有窗口的过程,但也许你可以过滤..

 var proc = new Process() { StartInfo = new ProcessStartInfo { FileName = "tasklist", Arguments = "/V", UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true } }; proc.Start(); StreamReader sr = proc.StandardOutput; while (!sr.EndOfStream) { string line = sr.ReadLine(); Match m = Regex.Match(line, @".{52}(\d+).{94}(.+)$");//157 if (m.Success) { int session = Convert.ToInt32(m.Groups[1].Value); string title = m.Groups[2].Value.Trim(); if (session == 1 && title != "N/A") sb.AppendLine(title); } } 

正如其他人所说,这是因为某些应用程序(Notepad ++是一个)没有MainWindowTitle,为了解决这个问题,我的代码(作为示例)如下所示:

 Process[] processes = Process.GetProcesses(); foreach (Process pro in processes) { if (pro.MainWindowTitle != "") { listBox.Items.Add(pro.ProcessName + " - " + pro.MainWindowTitle); } else { listBox.Items.Add(pro.ProcessName); } } 

你可以试试这样的克里斯

//下面的更新将为您提供在“应用程序”选项卡中运行的所有进程

 Process[] myProcesses = Process.GetProcesses(); foreach (Process P in myProcesses) { if (P.MainWindowTitle.Length > 1) { Console.WriteLine(P.ProcessName + ".exe"); Console.WriteLine(" " + P.MainWindowTitle); Console.WriteLine(""); } }