2012-05-24 3 views
4

Я использую приложение для настольных компьютеров, которое должно записывать имена и время программ, которые пользователь открывает на ПК. Это приложение C# (WPF), которое запускается, когда пользователь входит в систему и запускается без пользовательского интерфейса. Для таких программ, как Word или IE, он также фиксирует, какой документ или URL они просматривают.Как отслеживать открытие приложения?

В настоящее время у меня есть рабочий раствор следующим образом:

Установите крюк для Windows для мыши. Когда это событие срабатывает, я использую p-Invoke для «GetForegroundWindow», а затем использую дескриптор окна для «GetWindowThreadProcessId», а ProcessId могу получить объект System.Diagnostics.Process, содержащий имя, время начала и начало списка аргументов. Я сохраняю список истории, поэтому я пишу только запись отслеживания, если эта комбинация дескрипторов process/dd не была записана ранее.

Это решение работает нормально, но требует крючка для мыши, который может быть удален Windows без какого-либо уведомления или возможности проблемно проверить, все ли подключено. Не говоря уже о том, что эта реализация кажется взломанной.

Если есть более простой подход, проконсультируйтесь.

Спасибо.

+1

Почему бы не прочь с крюком мыши и просто использовать таймер #? – Blorgbeard

+0

похоже, что вы предлагаете опрос? Это моя стратегия резервного копирования, но не знаю, будет ли это ресурсоемкой, поскольку мне нужно будет опросить каждую секунду, чтобы получить надежные результаты. Тогда мне все равно нужно отслеживать историю, чтобы я только подсчитывал каждый процесс/окно один раз. Дайте мне знать, если я неправильно понял ваш совет. Благодарю. – JayDee

+0

Да - я имел в виду опрос. Я не думаю, что получить список процессов раз в секунду будет особенно ресурсоемким - но вы всегда можете попробовать и посмотреть? – Blorgbeard

ответ

11

Вы можете использовать событие __InstanceCreationEvent и класс WMI Win32_Process для мониторинга созданных процессов.

Попробуйте образец C приложение

using System; 
using System.Collections.Generic; 
using System.Management; 
using System.Text; 


namespace GetWMI_Info 
{ 
    public class EventWatcherAsync 
    { 
     private void WmiEventHandler(object sender, EventArrivedEventArgs e) 
     { 
      //in this point the new events arrives 
      //you can access to any property of the Win32_Process class 
      Console.WriteLine("TargetInstance.Handle : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Handle"]); 
      Console.WriteLine("TargetInstance.Name :  " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Name"]); 

     } 

     public EventWatcherAsync() 
     { 
      try 
      { 
       string ComputerName = "localhost"; 
       string WmiQuery; 
       ManagementEventWatcher Watcher; 
       ManagementScope Scope;     

       Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null); 
       Scope.Connect(); 

       WmiQuery ="Select * From __InstanceCreationEvent Within 1 "+ 
       "Where TargetInstance ISA 'Win32_Process' "; 

       Watcher = new ManagementEventWatcher(Scope, new EventQuery(WmiQuery)); 
       Watcher.EventArrived += new EventArrivedEventHandler(this.WmiEventHandler); 
       Watcher.Start(); 
       Console.Read(); 
       Watcher.Stop(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Exception {0} Trace {1}", e.Message, e.StackTrace); 
      } 

     } 

     public static void Main(string[] args) 
     { 
      Console.WriteLine("Listening process creation, Press Enter to exit"); 
      EventWatcherAsync eventWatcher = new EventWatcherAsync(); 
      Console.Read(); 
     } 
    } 
} 
+2

Отличное решение, отлично работает. И если кто-то хочет знать, как разбирать это загадочное время для процесса, вот фрагмент C#. DateTime.ParseExact (wmiDateFormat.Substring (0, 21), "yyyyMMddhhmsms.ffffff ", null); – JayDee

+0

Как узнать, когда приложение закрыто? Есть ли какой-либо конкретный запрос для этого случая? – LaPuyaLoca

+1

Чтобы обнаружить, когда приложение закрыто, попробуйте [__InstanceDeletionEvent] (https://msdn.microsoft.com/en -us/library/windows/desktop/aa394650 (v = vs.85) .aspx) class – RRUZ

2

Если вы хотите следить за производительностью всего, что работает на Windows, то это путь PerformanceCounter class. Каждый раз, когда приложение запускает окна, создается десятки счетчиков производительности для отслеживания ИД Процесса, использования ЦП, использования памяти, операций ввода-вывода в секунду и т. Д.

Например, следующий код даст вам в Chrome Process ID:

PerformanceCounter perf = new PerformanceCounter("Process", "ID Process", "chrome"); 
int procId = (int)perf.NextValue(); 

И вы также можете легко перечислить категории, экземпляры и счетчики с использованием PerformanceCounterCategory class.

Вы можете использовать Windows's PerfMon tool, чтобы получить представление о том, какую информацию вы сможете получить. Я предлагаю вам взглянуть на категорию (используя PerfMon), в котором вы найдете список всех активных процессов.

+0

аналогично приведенному выше предложению (по Blorgbeard), это, по-видимому, указывает на подход опроса. Если бы я использовал эту стратегию, я бы просто отслеживал список процессов, я не использую показатели производительности. Дайте мне знать, если есть что-то такое, что я пропустил. Благодарю. – JayDee

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