2013-01-08 24 views
6

Sto cercando di ottenere l'elenco di tutte le applicazioni aperte. In particolare, se apri il task manager e vai alla scheda Applicazioni, quella lista.Ottenere un elenco di tutte le applicazioni

Ho provato con qualcosa di simile:

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 
    { 
    } 
} 

Come in alcuni esempi che ho trovato, ma questo non tirare tutte le applicazioni per me. Mi piace solo la metà di quelli che posso vedere nel task manager o che so di avere aperto. Ad esempio, questo metodo non rileva Notepad ++ o Skype per qualche motivo, ma raccoglie Google Chrome, Calcolatrice e Microsoft Word.

Qualcuno sa o perché questo non funziona correttamente o come farlo?

Inoltre, un amico ha suggerito che potrebbe essere un problema di autorizzazioni, ma sto eseguendo Visual Studio come amministratore e non è cambiato.

EDIT: Il problema che sto ottenendo è che la maggior parte delle soluzioni che ho ricevuto restituisce solo un elenco di TUTTI i processi, che non è quello che voglio. Voglio solo le applicazioni o le finestre aperte, come l'elenco che appare sul task manager. Non un elenco di ogni singolo processo.

Inoltre, so che qui c'è del codice errato, incluso il blocco di blocco vuoto. Questo è stato un progetto buttato via per capire come funziona in primo luogo.

+2

probabile perché quelle applicazioni non hanno un titolo finestra principale. – cgTag

+0

se si programma ha un Titolo finestra principale si potrebbe fare qualcosa come questo processo Chris [] processes = Process.GetProcesses(); foreach (var proc nei processi) { if (! String.IsNullOrEmpty (proc.MainWindowTitle)) Console.WriteLine (proc.MainWindowTitle); } potresti anche usare 'WMI' http://msdn.microsoft.com/en-us/library/windows/desktop/aa394599%28v=vs.85%29.aspx – MethodMan

+2

Stai guardando il codice? stai copia-e-incolla? –

risposta

2

Come ha notato Mathew probabilmente perché non hanno titoli principali e quindi li stai filtrando. Il codice seguente ottiene tutti i processi in esecuzione. È quindi possibile utilizzare Process.ProcessName per filtrare quello che non si desidera. Here è la documentazione sull'utilizzo di ProcessName.

using System.Diagnostics; 

Process[] processes = Process.GetProcesses(); 

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

Immagino che la cosa di cui sono confuso sia che non so esattamente cosa voglio filtrare, se questo ha senso. So che voglio tutte le applicazioni in esecuzione, ma come posso verificarlo? La maggior parte delle cose che ho visto su questo argomento è che se un'applicazione ha una finestra, ha un MainWindowTitle, quindi come faccio ad ottenere cose come Notepad ++ che apparentemente non lo fanno? –

+0

@ChrisBacon Ha ancora un processname o un processid, se è in esecuzione! – FrostyFire

+0

Perché il downrate ??????????????????? – FrostyFire

0

Si può provare qualcosa di simile Chris

// AGGIORNATO sotto ti porterà tutti i processi in esecuzione nella scheda Application

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

Il mio problema con questa soluzione è che mi dà ancora ogni processo in esecuzione, che non è quello che voglio. Io voglio solo processi _con windows_. Fondamentalmente tutto quello che voglio sono le applicazioni che posso vedere nella scheda Applicazioni del mio task manager. –

+0

@ChrisBacon vedere la mia risposta aggiornata – MethodMan

0

Come altri hanno detto che è perché alcune applicazioni (Notepad ++ essendo uno) non hanno un MainWindowTitle, per contrastare questo il mio codice (ad esempio) si presenta così:

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

Il mio problema con questa soluzione è che mi dà ancora tutti i processi in esecuzione, che non è quello che voglio. Voglio solo i processi con Windows. Fondamentalmente tutto quello che voglio sono le applicazioni che posso vedere nella scheda Applicazioni del mio task manager. –

0

Penso che, per qualche ragione, MainWindowTitle sia nullo per alcuni processi, quindi stai saltando quelli. Prova questo solo per il test:

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

Forse il tuo try ... catch sta saltando alcuni processi se ottiene qualche errore, in modo da provare senza di essa anche.

UPDATE: Prova questa, è brutto e prendere alcuni processi che non ha finestre ma forse è possibile filtrare ..

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

Ho provato a rimuovere il blocco try/catch, ma ignora ancora alcune finestre. E il problema principale è che non voglio ogni singolo processo, voglio solo quelli con Windows associati a loro. –

+0

Chris, il tuo codice funziona nel mio computer, inclusi Skype e Notepad ++. Quali versioni di windows e framework stai usando? –

10

L'esempio di codice here sembra dare quello che stai chiedendo. versione modificata:

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

Con il codice precedente, chiamando User32Helper.GetDesktopWindows() dovrebbe dare un elenco di contenere il manico/Titolo per tutte le applicazioni aperte, così come se o non sono visibili.Si noti che true viene restituito indipendentemente dalla visibilità della finestra, poiché l'elemento verrà comunque visualizzato nell'elenco delle applicazioni di Task Manager come richiesto dall'autore.

È quindi possibile utilizzare la proprietà Handle corrispondente da uno degli elementi nella raccolta per eseguire una serie di altre attività utilizzando altri Window Functions (come ShowWindow o EndTask).

+0

Funziona alla grande. Nel caso si stia tentando di chiudere una finestra specifica e non l'intera applicazione, consiglio questa [risposta] (http://stackoverflow.com/questions/1694451/cannot-use-pinvoke-to-send-wm-close-to- a-windows-explorer-finestra). DestroyWindow (https://msdn.microsoft.com/en-us/library/windows/desktop/ms632682%28v=vs.85%29.aspx) funziona solo dalla stessa discussione e CloseWindow (https://msdn.microsoft .com/it/us/library/windows/desktop/ms632678% 28v = vs.85% 29.aspx) minimizza solo la finestra di destinazione. –

Problemi correlati