I am implementing a tracker for my system which will track user active time and idle time. I am not able to get idle time from the following code. Can any body help me?
My code is as follows:
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;
namespace Ultimate_Tracker
{
public partial class Form1 : Form
{
private bool start = false;
private Timer timer;
private bool toggleTrackerButton = true;
private DateTime lastActivityTime;
private TimeSpan trackedTime;
private TimeSpan idleTime;
// Hook handles
private IntPtr mouseHookHandle;
private IntPtr keyboardHookHandle;
private bool idleTimeAlertShown=true;
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public Form1()
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
{
InitializeComponent();
timer = new Timer();
int interval = GetRandomInterval();
if (interval != 0)
{
timer.Interval = interval;
}
else
{
timer.Interval = 1;
}
timer.Tick += timer1_Tick;
lastActivityTime = DateTime.Now;
// Start the mouse and keyboard hooks
StartHooks();
}
// Import the user32.dll
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private const int WH_MOUSE_LL = 14;
private const int WH_KEYBOARD_LL = 13;
private const int WM_MOUSEMOVE = 0x0200;
private const int WM_KEYDOWN = 0x0100;
// Hook callbacks
private IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && (int)wParam == WM_MOUSEMOVE)
{
ResetIdleTimer();
}
return CallNextHookEx(mouseHookHandle, nCode, wParam, lParam);
}
private IntPtr KeyboardHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && (int)wParam == WM_KEYDOWN)
{
ResetIdleTimer();
}
return CallNextHookEx(keyboardHookHandle, nCode, wParam, lParam);
}
private void StartHooks()
{
using (ProcessModule module = Process.GetCurrentProcess().MainModule)
{
IntPtr moduleHandle = GetModuleHandle(module.ModuleName);
// Set the mouse hook
mouseHookHandle = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, moduleHandle, 0);
if (mouseHookHandle == IntPtr.Zero)
{
// Handle hook setup failure (if needed)
}
// Set the keyboard hook
keyboardHookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookCallback, moduleHandle, 0);
if (keyboardHookHandle == IntPtr.Zero)
{
// Handle hook setup failure (if needed)
}
}
}
private void StopHooks()
{
// Unhook the mouse hook
if (mouseHookHandle != IntPtr.Zero)
{
UnhookWindowsHookEx(mouseHookHandle);
mouseHookHandle = IntPtr.Zero;
}
// Unhook the keyboard hook
if (keyboardHookHandle != IntPtr.Zero)
{
UnhookWindowsHookEx(keyboardHookHandle);
keyboardHookHandle = IntPtr.Zero;
}
}
private void Form1_Load(object sender, EventArgs e)
{
toggleTracker.FlatStyle = FlatStyle.Flat;
toggleTracker.FlatAppearance.BorderSize = 0;
this.MouseMove += Form1_MouseMove;
this.KeyPress += Form1_KeyPress;
}
private void Form1_KeyPress(object? sender, KeyPressEventArgs e)
{
ResetIdleTimer();
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
ResetIdleTimer();
}
private void ResetIdleTimer()
{
if (idleTimeAlertShown)
{
idleTimeAlertShown = false;
idleTime = TimeSpan.Zero;
}
lastActivityTime = DateTime.Now;
}
private void timer1_Tick(object sender, EventArgs e)
{
TimeSpan currentTime = DateTime.Now - lastActivityTime;
trackedTime += currentTime;
lastActivityTime = DateTime.Now;
// perform some activity
lastActivityTime = DateTime.Now;
}
private void toggleTracker_Click(object sender, EventArgs e)
{
if (!toggleTrackerButton)
{
// Reset the trackedTime and idleTime when starting the tracker
trackedTime = TimeSpan.Zero;
idleTime = TimeSpan.Zero;
idleTimeAlertShown = true; // Set to true to show the first idle alert
toggleTracker.BackgroundImage = Properties.Resources.btnRed;
toggleTrackerButton = true;
timer.Start();
}
else
{
toggleTracker.BackgroundImage = Properties.Resources.btnGreen;
toggleTrackerButton = false;
timer.Stop();
MessageBox.Show("Tracked Time: " + trackedTime.ToString() + "\nIdle Time: " + idleTime.ToString());
}
}
}
}
I tried to implemet tracker and get user active time and idle time. I can get active time clearly but not able to get idle time.
Based on your response to my comment, I felt like you could do with some more context around
Stopwatch- maybe this will solve your problem.In your current approach you are manually recording (and resetting to zero) a
TimeSpan.I'd suggest using a
Stopwatchinstead. You can call.Restart(). to set it back to zero, and.Ellapsedto get theTimeSpanrepresenting the time since it was last restarted.Example using your code (I don't want to write this for you so I've simplified to only the relevant parts):
Hope this helps :)