2013-01-08 21 views
6

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

我用这样的尝试:

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,但可以使用Google Chrome,计算器和Microsoft Word。

有谁知道为什么这不能正常工作或如何做?

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

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

此外,我知道这里有错误的代码,包括空的catch块。这是一个一劳永逸的计划,只是为了弄清楚这是如何工作的。

+2

可能是因为这些应用没有主窗口标题。 – cgTag

+0

如果你的程序有一个主窗口标题你可以做这样的事情Chris Process [] processes = Process.GetProcesses(); foreach(var proc in processes) if(!string.IsNullOrEmpty(proc.MainWindowTitle)) Console.WriteLine(proc.MainWindowTitle); } 你也可以使用'WMI' http://msdn.microsoft.com/en-us/library/windows/desktop/aa394599%28v=vs.85%29.aspx – MethodMan

+2

你甚至在看你的代码'复制和粘贴? –

回答

2

正如马修指出,它可能是因为他们没有主要标题,因此你过滤出来。下面的代码获取所有正在运行的进程。然后,您可以使用Process.ProcessName来筛选出你不想要的。 Here是有关使用ProcessName的文档。

using System.Diagnostics; 

Process[] processes = Process.GetProcesses(); 

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

我想我所困惑的是,我不知道我想要过滤,如果这是有道理的。我知道我想要所有正在运行的应用程序,但我如何检查它?我在这个问题上看到的大部分事情是,如果应用程序有一个窗口,它有一个MainWindowTitle,那么我怎么会得到像Notepad ++这样的东西,显然没有? –

+0

@ChrisBacon它仍然有一个processname或processid,如果它正在运行! – FrostyFire

+0

为什么减少??????????????????? – FrostyFire

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

我对这个解决方案的问题是,它仍然只是给我每一个进程运行,这不是我想要的。我只想要windows_的进程。基本上我想要的是我可以在我的任务管理器的应用程序选项卡中看到的应用程序。 –

+0

@ChrisBacon查看我的更新回答 – MethodMan

0

正如其他人说,这是因为有些应用程序(记事本+是一个)没有一个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); 
    } 
} 
+0

我对这个解决方案的问题是,它仍然只是给我每个进程运行,这不是我想要的。我只想使用Windows进程。基本上我想要的是我可以在我的任务管理器的应用程序选项卡中看到的应用程序。 –

0

我认为,出于某种原因,一些进程的MainWindowTitle为空,所以你跳过那些。试试这个只是测试:

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

也许你的TRY ... CATCH是跳跃的一些过程,如果它得到了一些错误,所以尽量不还。

UPDATE: 试试这个,它的丑陋,并采取不设窗户一定过程,但也许你可以过滤..

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

我试图带走try/catch块,但它仍然忽略了一些窗口。主要的问题是我不想要每一个进程,我只想要那些与他们相关的窗口。 –

+0

Chris,您的代码在我的电脑中运行,包括Skype和Notepad ++。你使用的是什么窗口和框架版本? –

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)。

+0

工程很棒。如果你想关闭一个特定的窗口而不是整个应用程序,我推荐这个[answer](http://stackoverflow.com/questions/1694451/cannot-use-pinvoke-to-send-wm-close-to-一个窗口资源管理器窗口)。 DestroyWindow(https://msdn.microsoft.com/en-us/library/windows/desktop/ms632682%28v=vs.85%29.aspx)只能从相同的线程和CloseWindow(https://msdn.microsoft .com/en-us/library/windows/desktop/ms632678%28v = vs.85%29.aspx)只会最小化目标窗口。 –

相关问题