2013-01-08 42 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)只會最小化目標窗口。 –

相關問題