获取所有应用程序的列表

时间:2013-01-08 02:49:30

标签: c# process

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

我尝试过这样的事情:

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,但是它们会选择谷歌Chrome,计算器和Microsoft Word。

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

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

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

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

5 个答案:

答案 0 :(得分:10)

代码示例here似乎可以满足您的要求。修改版:

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<DesktopWindow> GetDesktopWindows()
    {
        var collection = new List<DesktopWindow>();
        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属性,使用其他Window Functions(例如ShowWindowEndTask)执行许多其他任务。< / p>

答案 1 :(得分:2)

正如Mathew所指出的那样,可能是因为他们没有主要标题,因此你将其过滤掉了。以下代码将运行所有进程。然后,您可以使用Process.ProcessName过滤掉您不想要的那个。 Here是有关使用ProcessName的文档。

using System.Diagnostics;

Process[] processes = Process.GetProcesses();

foreach (Process process in processes)
{
   //Get whatever attribute for process
}

答案 2 :(得分:0)

你可以试试像这样的东西

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

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("");
    }
}

答案 3 :(得分:0)

正如其他人所说,这是因为某些应用程序(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);
    }
}

答案 4 :(得分:0)

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

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

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

<强>更新 试试这个,它很丑陋,并采取一些没有窗口的过程,但也许你可以过滤..

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);
    }
}