我试图获取所有打开的应用程序的列表。具体来说,如果您打开任务管理器并转到应用程序选项卡,该列表。
我尝试过这样的事情:
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块。这是一个一次性的项目,只是为了弄清楚这是如何起作用的。
答案 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(例如ShowWindow或EndTask)执行许多其他任务。< / 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);
}
}