2012-01-15 3 views
6

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

+1

Да, постоянный опрос является неправильным решением по многим причинам, не последним из которых является ухудшение производительности. Вы ищете крючок. Но вы не можете написать DLL-ссылку на C#; вам нужно использовать для этого C или C++. –

+0

Какую цель ставите перед собой? Трудно дать вам ответ, который решает вашу проблему. Вы хотите отслеживать запуск любого процесса или только начало определенного процесса? Вам нужно точно выполнить время выполнения контролируемых процессов или вас интересуют только процессы, которые работают дольше, например. 10 минут? В зависимости от вашего ответа может оказаться, что опрос является «хорошим» компромиссом. Есть точные способы сделать это, но они значительно сложнее. –

+0

Извините, ** Английский язык для меня трудно. Я хочу измерить время запуска процесса и зарегистрировать его в txt-файле. Но я не хочу проверять его каждую секунду. –

ответ

3

Первоначально определите для всех запущенных процессов время создания. Затем использует WMI для регистрации событий процесса.

Смотрите ниже код для небольшого примера о том, как использовать WMI для событий создания процесса:

static void Main(string[] args) 
{ 
    using (ManagementEventWatcher eventWatcher = 
      new ManagementEventWatcher(@"SELECT * FROM 
    __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'")) 
    { 
    // Subscribe for process creation notification. 
    eventWatcher.EventArrived += ProcessStarted_EventArrived; 
    eventWatcher.Start(); 
    Console.In.ReadLine(); 
    eventWatcher.EventArrived -= ProcessStarted_EventArrived; 
    eventWatcher.Stop(); 
    } 
} 


static void ProcessStarted_EventArrived(object sender, EventArrivedEventArgs e) 
{ 
    ManagementBaseObject obj = e.NewEvent["TargetInstance"] as ManagementBaseObject; 

    // The Win32_Process class also contains a CreationDate property. 
    Console.Out.WriteLine("ProcessName: {0} " + obj.Properties["Name"].Value); 
} 

НАЧАТЬ EDIT: обнаружение создания процесса

Я дальше изученного с помощью WMI и там (но нуждается в административных привилегиях) с использованием класса Win32_ProcessStartTrace (дополнительную информацию см. в разделе TECHNET):

using (ManagementEventWatcher eventWatcher = 
      new ManagementEventWatcher(@"SELECT * FROM Win32_ProcessStartTrace")) 
{ 
    // Subscribe for process creation notification. 
    eventWatcher.EventArrived += ProcessStarted_EventArrived; 
    eventWatcher.Start(); 
    Console.Out.WriteLine("started"); 
    Console.In.ReadLine(); 
    eventWatcher.EventArrived -= ProcessStarted_EventArrived; 
    eventWatcher.Stop(); 
} 

static void ProcessStarted_EventArrived(object sender, EventArrivedEventArgs e) 
{    
    Console.Out.WriteLine("ProcessName: {0} " 
      + e.NewEvent.Properties["ProcessName"].Value);  
} 

В этом решении вам не нужно устанавливать интервал опроса.

END EDIT

НАЧАТЬ EDIT 2:

Вы можете использовать Win32_ProcessStopTrace класс контролировать процесс остановки событий. Чтобы объединить оба процесса и события остановки процесса, используйте класс Win32_ProcessTrace. В обработчик событий с помощью ClassPath proberty различать старт/стоп события:

using (ManagementEventWatcher eventWatcher = 
     new ManagementEventWatcher(@"SELECT * FROM Win32_ProcessTrace")) 
{   
    eventWatcher.EventArrived += Process_EventArrived; 
    eventWatcher.Start(); 
    Console.Out.WriteLine("started"); 
    Console.In.ReadLine(); 
    eventWatcher.EventArrived -= Process_EventArrived; 
    eventWatcher.Stop(); 
} 

static void Process_EventArrived(object sender, EventArrivedEventArgs e) 
{ 
    Console.Out.WriteLine(e.NewEvent.ClassPath); // Use class path to distinguish 
               // between start/stop process events. 
    Console.Out.WriteLine("ProcessName: {0} " 
     + e.NewEvent.Properties["ProcessName"].Value);  
} 

END EDIT 2

+0

-1 первый WMI делает внутренний пул. Во-вторых, вам не нужно даже использовать WMI. ОС уже записывает время начала каждого процесса. Все, что вам нужно сделать, это прочитать его. См. Мой ответ ниже. –

+0

Спасибо. Есть ли способ проверить процессы закрытия тоже? –

+1

@ MoctavaFarzán: Да, также есть событие __InstanceDeletionEvent. Но если вы планируете использовать как __InstanceDeletionEvent, так и __InstanceCreationEvent, вы должны подписаться на __InstanceOperationEvent, а затем проверить свой обратный вызов, какое событие было уволено, оценив свойство e.NewEvent.ClassPath.ClassName. – Hans

2

Там нет необходимости контролировать что-либо вообще. Все, что вам нужно сделать, - перечислить процессы и выборки из экземпляров процесса StartTime.

+0

Но вам, безусловно, нужно использовать таймер или что-то в этом роде? Перечислить процессы один раз недостаточно. Итак, я не понимаю, почему вы проголосовали за мой ответ? – Hans

+0

Есть способы достичь этого без таймера. Основная проблема с вашим ответом заключается в том, что с «__InstanceCreationEvent WITHIN 1» вы делаете опрос каждую секунду. Если процесс начинается и останавливается в течение этого времени, вы никогда не получите никакого уведомления. Если вы знаете, какой процесс вы хотите проверить, вы можете получить обратный вызов из ОС при использовании параметров выполнения файлов изображений. Но сначала Фарзан должен указать, как он получает рассматриваемые процессы и которые ему интересны. Есть много способов добиться этого. –

+0

Да, я aggree. Существует множество решений, таких как Параметры выполнения файлов изображений, Крючки, опрос с использованием таймера, использование WMI или использование драйвера. Итак, я действительно не понял твоего голоса. – Hans

Смежные вопросы