I'm implementing a desktop analytics application that needs to record the names and times of programs a user opens on the PC. It's a C# (WPF) application that starts when the user logs on and runs without a UI. For programs such as Word or IE it would also capture what document or Url they are viewing.
Currently I have a working solution as follows:
Install a Windows Hook for Mouse Down. When that event fires I use p-Invoke to "GetForegroundWindow" and then use the window handle to "GetWindowThreadProcessId", with the ProcessId I can get the System.Diagnostics.Process object containing the name, start time and argument start list. I maintain a history list so I only write a tracking entry if this processId/window handle combination has not been recorded before.
This solution does work ok but requires the mouse hook which can get dropped by Windows without any notification or ability to problematically check if it is still hooked. Not to mention this implementation seems like a hack.
If there is a better more straightforward approach please advise.
Thanks.
1] Move apps to the desired monitor To do so, open the app on your computer first. Then, drag or move it to the desired monitor you want to open it on. Following that, close the app by clicking the Close or red cross button. After that, it will open on the last opened monitor all the time.
Task Manager displays all apps and background processes that are running on your PC. You can open it quickly by pressing Control + Shift + Esc at the same time, or by right-clicking the taskbar and selecting Task Manager. When Task Manager opens, you'll see a brief list of open apps.
Right-click the program on the taskbar, and then click Move. Move the mouse pointer to the middle of the screen. Use the ARROW keys on the keyboard to move the program window to a viewable area on the screen. Press ENTER.
Hold down the Shift key, then right-click on the appropriate application icon in the Windows taskbar. On the resulting pop-up, select the Move option. Begin pressing the arrow keys on your keyboard to move the invisible window from off-screen to on-screen.
You can use the __InstanceCreationEvent
event and the Win32_Process
WMI class to monitor the created processes.
Try this sample C# application
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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With