2010-08-11 3 views
3

Я использую приведенный ниже код, чтобы найти любой новый процесс. Эта функция работает в потоке.Ищите новый процесс, запущенный с помощью C#

Мне нужно ввести имя процесса. Для чего я использую два arraylist. На одном arraylist я сохраняю все имена процессов до того, как он начнет поток, а другой arraylist, заполните текущий процесс внутри потока и сравните два arraylist, чтобы найти новый процесс.

Проблема в том, что строка для записи в файл журнала находится для каждого цикла, я вижу повторные имена процессов в файле журнала. Я хочу, чтобы он регистрировался только один раз. Как я могу это решить?

class ProcessMonitor 
{ 
    public static ArrayList ExistingProcess = new ArrayList(); 


    public static void Monitor() 
    { 
     existingProcesses = GetExistingProcess(); 

     while (true) 
     { 
      ArrayList currentProcesses = new ArrayList(); 
      currentProcesses = GetCurrentProcess(); 

      ArrayList NewApps = new ArrayList(GetCurrentProcess()); 

      foreach (var p in ExistingProcess) 
      { 
       NewApps.Remove(p); 
      } 
      string str = ""; 
      foreach (string NewApp in NewApps) 
      { 
       str += "Launched ProcessName/ID : " + NewApp + "/" + System.Diagnostics.Process.GetProcessesByName(NewApp)[0].Id.ToString() + Environment.NewLine; 
      } 
      if(str!="") 
      { 
       Log.Info(str); 
      } 
     } 
    } 

    public static ArrayList GetExistingProcess() 
    { 
     Process[] processlist = Process.GetProcesses(); 
     foreach (Process Proc in processlist) 
     { 
      ExistingProcess.Add(Proc.ProcessName); 
     } 
     return ExistingProcess; 
    } 
    public static ArrayList GetCurrentProcess() 
    { 
     ArrayList CurrentProcesses = new ArrayList(); 
     Process[] processlist = Process.GetProcesses(); 
     foreach (Process Proc in processlist) 
     { 
      CurrentProcesses.Add(Proc.ProcessName); 
     } 
     return CurrentProcesses; 
    } 
} 
+0

Использовать набор данных (хэш-набор) данных + цикл foreach возможно? –

+0

@Hamish Grubijan, не могли бы вы дать мне пример, пожалуйста .. спасибо – Anuya

+0

, вы больше не должны использовать 'ArrayList'. Вместо этого используйте «Список ». –

ответ

4

Итерационные процессы в Windows очень дороги. Есть лучший способ сделать это с классом WMI, Win32_ProcessStartTrace. Он также автоматически решает вашу проблему, так как он расскажет вам о начале новых процессов. И не нужна нить.

Вы найдете код, который вам нужен, в this answer.

1

Я не совсем уверен, что вы здесь делаете, но первые две строки и последняя строка из выдержки ниже в основном делают то же самое, только последняя строка является более дорогостоящей (поскольку вы создаете второй список массивов от одного возвращенного GetCurrentProcess:.

ArrayList currentProcesses = new ArrayList(); 
currentProcesses = GetCurrentProcess(); 

ArrayList NewApps = new ArrayList(GetCurrentProcess()); 

Во-вторых, у вас никогда не использовать переменную currentProcess, насколько я могу сказать ... так что его 100% отходов в-третьих, почему это проблема, если есть дубликаты имен процессов? Тот же процесс можно запускать несколько раз, более одного экземпляра процесса может выполняться одновременно, процесс может запускаться, останавливаться, затем запускаться снова и т. д. Это не обязательно «неправильно» для процес имя которого будет указано дважды.

(ОБНОВЛЕНИЕ: одна причина, по которой вы можете получать «дубликаты» в своем журнале, заключается в том, что вы получаете existingProcesses только один раз. Каждый раз через цикл (который, кстати, будет происходить с максимальной скоростью непрерывно), вы будете получать список процессов снова и сравнение их с оригиналом existingProcesses, поэтому те же процессы, перечисленные в предыдущем цикле ... если они все еще запущены, будут перечислены снова. Я обновил свой пример кода, чтобы продемонстрировать, как решить эту проблему проблема.)

У вас, кажется, есть некоторые фундаментальные ошибки кода и, возможно, недостатки в ваших ожиданиях. Я бы пересмотрел ваш код в целом, устранил бесполезный код (например, первые две строки выше) и вообще упорядочил ваш код. (Подсказка: ArrayList - ДЕЙСТВИТЕЛЬНО Плохой выбор ... Я бы использовал IEnumerable<T>, который не требует никакого преобразования или совокупности из необработанного массива). Если бы я должен был продублировать код выше с более эффективным кодом:

public static void Monitor() 
{ 
    var existingProcesses = Process.GetProcesses(); 

    bool doProcessing = true; 
    while (doProcessing) 
    { 
     var currentProcesses = Process.GetProcesses(); 

     var newProcesses = currentProcesses.Except(existingProcesses); 

     int capacity = newProcesses.Count() * 60; 
     var builder = new StringBuilder(capacity); 
     foreach (var newProcess in newProcesses) 
     { 
      builder.Append("Launched ProcessName/ID : "); 
      builder.Append(newProcess.ProcessName); 
      builder.Append("/"); 
      builder.Append(newProcess.Id); 
      builder.AppendLine(); 
     } 

     string newProcessLogEntry = builder.ToString(); 
     if(!String.IsNullOrEmpty(newProcessLogEntry)) 
     { 
      Log.Info(newProcessLogEntry); 
     } 

     existingProcesses = currentProcesses; // Update existing processes, so you don't reprocess previously processed running apps and get "duplicate log entries" 

     if (requestToStopMonitoring) // do something to kill this loop gracefully at some point 
     { 
      doProcessing = false; 
      continue; 
     } 

     Thread.Sleep(5000); // Wait about 5 seconds before iterating again 
    } 
} 
Смежные вопросы