Вывести список приложений

430
10 мая 2017, 06:21

Приветствую. Пишу небольшую утилиту для windows. Требуется вывести список всех запущенных приложений и периодически по Tick таймера его обновлять. Например если запущено новое приложение вывести сообщение, если закрыто старое то вывести сообщение о том какое было закрыто. Вот событие по Tick таймера :

    List<string> ProcessOld = new List<string>();
    private void processGet(object s, EventArgs e)
    {
        var process = System.Diagnostics.Process.GetProcesses();
        try
        {
            foreach (System.Diagnostics.Process i in process)
            {
                if (i.MainWindowTitle != string.Empty)
                {
                    if (!ProcessOld.Contains(i.MainWindowTitle))
                    {
                        ProcessOld.Add(i.MainWindowTitle.ToString());
                        foreach (string SP in ProcessOld)
                        {
                            textBox1.Text += "Запущен процесс :: " + SP.ToString() + "\r\n";
                        } 
                    }
                    else
                    {
                    }
                }
            }
        }
        catch (Exception ex)
        {
        }
    }

Работает вроде без ошибок но каждое приложение выводит по 2 раза и если будет запущено новое то выведет полный список из ProcessOld а не только новое запущенное, подскажите как это исправить? И подскажите как реализовать вывод сообщения о том что старый процесс был закрыт?

Answer 1

2 раза выводит название каждого приложения потому, что вы в цикле по всем процессам выводите список ProcessOld. Нужно исправить код так:

List<string> ProcessOld = new List<string>();
private void processGet(object s, EventArgs e)
{
    var process = System.Diagnostics.Process.GetProcesses();
    try
    {
        foreach (System.Diagnostics.Process i in process)
        {
            if (i.MainWindowTitle != string.Empty)
            {
                if (!ProcessOld.Contains(i.MainWindowTitle))
                {
                    ProcessOld.Add(i.MainWindowTitle.ToString()); 
                }
            }
        }
        foreach (string SP in ProcessOld)
            textBox1.Text += "Запущен процесс :: " + SP.ToString() + "\r\n";
    }
    catch (Exception ex)
    {
    }
}

Для того, чтобы реализовать вывод сообщения о том, какое-то приложение закрылось, нужно пройтись в цикле по все процессам, добавить их в некоторый List<System.Diagnostics.Process> processes и затем пройтись по списку OldProcesses и для каждого элемента этого списка проверить, есть ли процесс с таким именем в списке processes.

Если есть, то удаляем элемент из списка OldProcesses. И в конечном итоге в списке останутся только те процессы, которых уже нет в текущем списке процессов.

Answer 2

Нашел такое решение : Каждый раз при срабатывании Tick таймера выполняется processGet

    List<string> ALLinTIME = new List<string>();
    List<string> VivodProc = new List<string>();
    private void processGet(object s, EventArgs e)
    {
    var process = System.Diagnostics.Process.GetProcesses();
      try
        {
            ALLinTIME.Clear();
                foreach (System.Diagnostics.Process i in process)
                {
                    if (i.MainWindowTitle != string.Empty)
                    {
                         ALLinTIME.Add(i.MainWindowTitle.ToString());
                    }
                }
                foreach (string proc in ALLinTIME)
                {
                    if (!VivodProc.Contains(proc))
                    {
                        VivodProc.Add(proc);
                        textBox1.Text += "Запущен процесс :: " + proc.ToString() + "\r\n";
                    }
                }
                foreach(string _proc in VivodProc)
                {
                    if (!ALLinTIME.Contains(_proc))
                    {
                        textBox1.Text += "Закрыт процесс :: " + _proc.ToString() + "\r\n";
                        VivodProc.Remove(_proc);
                    }
                }
                textBox1.Text += "-------------------------" + "\r\n"; 
        }

Далеко не самое изящное решение, но работает как и хотел.

Answer 3

По моему как то сложно вы решаете задачу. Я написал пример суть попроще, надеюсь вам поможет.

void Main()
{
    var timer = new Timer(Callback, null, 1000, 1000);  
    Console.ReadLine();
}
string[] actualProcesses = new string[0];
private void Callback(object state)
{
    var oldProcDict = new HashSet<string>(actualProcesses.Distinct());      
    var newProceses = GetProcesses();       
    var newProcDict =  new HashSet<string>(newProceses.Distinct());
    var added = newProcDict.Where(x=>oldProcDict.Contains(x) == false).ToArray();
    var removed = oldProcDict.Where(x=>newProcDict.Contains(x) == false).ToArray();
    foreach (var proc in added) 
        Console.WriteLine($"{proc} was added"); 
    foreach (var proc in removed)
        Console.WriteLine($"{proc} was removed");   
    actualProcesses = newProceses;
}
private string[] GetProcesses() => 
    System.Diagnostics.Process.GetProcesses()
        .Select(x=>x.MainWindowTitle).Where(x=>string.IsNullOrEmpty(x) == false).ToArray();
READ ALSO
C# парсинг строки и конвертация в double

C# парсинг строки и конвертация в double

Строка была получена таким образом:

353
Создание Add-in для Office в Visual Studio

Создание Add-in для Office в Visual Studio

Поставил пакет разработки расширений для офиса, но в списке шаблонов не могу найти Access, хотя все остальные шаблоны офисных проектов присутствуют(Word,...

234
Конвертирование строк c#

Конвертирование строк c#

Как конвертировать строку в c# чтобы кириллица нормально отображалась? Пример: "\u043f\u0440\u0438\u0432\u0435\u0442" должно стать "привет"

372
ветвь кода с if

ветвь кода с if

Всем привет, имеется вот такой if, у которого понятное дело есть else:

456