Tutorial :How to track application usage? [duplicate]



Question:

This question is an exact duplicate of:

I would like to develop an application (that runs at all times in the background I guess) to track the usage of applications (msword, excel, powerpoint, *.exe, etc.).

I can handle posting the data to a database but don't exactly know where to start with monitoring running applications (when they start, when they stop). Anyone have any clues?


Solution:1

You can periodically poll a list of the running processes using System.Diagnostics.Process.GetProcesses().

This following code outputs information about starting and exiting processes. Exiting system processes won't be recognized.

class Program  {      struct ProcessStartTimePair      {          public Process Process { get; set; }          public DateTime StartTime { get; set; }          public DateTime ExitTime          {              get              {                  return DateTime.Now; // approximate value              }          }            public ProcessStartTimePair(Process p) : this()          {              Process = p;              try              {                  StartTime = p.StartTime;              }              catch (System.ComponentModel.Win32Exception)              {                  StartTime = DateTime.Now; // approximate value              }          }      }        static void Main(string[] args)      {          List<ProcessStartTimePair> knownProcesses = new List<ProcessStartTimePair>();          while (true)          {              foreach (Process p in Process.GetProcesses())              {                  if (!knownProcesses.Select(x => x.Process.Id).Contains(p.Id))                  {                      knownProcesses.Add(new ProcessStartTimePair(p));                      Console.WriteLine("Detected new process: " + p.ProcessName);                  }              }                for (int i = 0; i < knownProcesses.Count; i++)               {                  ProcessStartTimePair pair = knownProcesses[i];                  try                  {                      if (pair.Process.HasExited)                      {                          Console.WriteLine(pair.Process.ProcessName + " has exited (alive from {0} to {1}).", pair.StartTime.ToString(), pair.ExitTime.ToString());                          knownProcesses.Remove(pair);                          i--; // List was modified, 1 item less                          // TODO: Store in the info in the database                      }                  }                  catch (System.ComponentModel.Win32Exception)                  {                      // Would have to check whether the process still exists in Process.GetProcesses().                      // The process probably is a system process.                  }              }              Console.WriteLine();              System.Threading.Thread.Sleep(1000);          }      }  }  

You probably can simply ignore system processes that don't let you read the HasExited property.

Edit

Here's a .net 2.0 version:

    static void Main(string[] args)      {          List<ProcessStartTimePair> knownProcesses = new List<ProcessStartTimePair>();          while (true)          {              foreach (Process p in Process.GetProcesses())              {                  if (!ProcessIsKnown(knownProcesses, p.Id))                  {                      knownProcesses.Add(new ProcessStartTimePair(p));                      Console.WriteLine("Detected new process: " + p.ProcessName);                  }              }                for (int i = 0; i < knownProcesses.Count; i++)               [...]          }      }        static bool ProcessIsKnown(List<ProcessStartTimePair> knownProcesses, int ID)      {          foreach (ProcessStartTimePair pstp in knownProcesses)          {              if (pstp.Process.Id == ID)              {                  return true;              }          }          return false;      }  

Note that the code could be improved and only shows the concept.


Solution:2

You could poll all top-level windows periodically and record the Window title text; and based on that do some conclusions as to which program are running.

Or you could do it via process name, or a combination.

For enumerating windows, see http://msdn.microsoft.com/en-us/library/ms633497(VS.85).aspx, and here is how to use it in managed code. For enumerating processes, use the Process.GetProcesses method or see http://www.codeproject.com/KB/threads/enumprocess.aspx


Solution:3

It's possible to use WMI to be notified when processes start/exit

A full working example is in a blog post on ASP.NET.

The basics of it (copied from the blog post for posterity):

Create a class that inherits from ManagementEventWatcher

Inside the constructor, set:

this.Query.QueryLanguage = "WQL";  this.Query.QueryString = @"SELECT * FROM   __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'";  this.EventArrived += watcher_EventArrived; // Delegate for EventArrivedEventHandler  

Make an EventArrivedEventHandler like:

private void watcher_EventArrived(object sender, EventArrivedEventArgs e)  {      string eventType = e.NewEvent.ClassPath.ClassName;      Win32_Process proc = new           Win32_Process(e.NewEvent["TargetInstance"] as ManagementBaseObject);        switch (eventType)      {          case "__InstanceCreationEvent":              Console.WriteLine("Process Created");              break;          case "__InstanceDeletionEvent":              Console.WriteLine("Process Deleted (Ended)");              break;          case "__InstanceModificationEvent":              Console.WriteLine("Process Modified (possibly still running)");              break;      }  }  


Solution:4

Polling is easy but you should really hook into the win32 events and instead receive notifications of when these things happens.

I have a similar side project to create a "task bar" type application. My goal is for the app to be notified when windows are moved/created/closed so I can use this information for displaying/updating a UI.

bb4win app has this "layer" where it can catch different kind of notifications from the system and uses it to create an alternative desktop shell. The source code is avail and is coded in c.

This is the link that I used to get started with the Win32 Hooks.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »