Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the total time a user spending on an application?

Tags:

.net

vb.net

I want to create an application that able to calculate the total time the user (i.e. myself) spent on a particular application, for example Firefox. And this application should display warning message if the user spent a lot of time on Firefox (for example 1 hour or more)

Reason: I'm a VB.NET developer. During my working hours, my main tool is Visual Studio and I suppose to do coding. But I need Firefox occasionally to access internet (particularly SO and other sites) to find solutions for my programming problems. The problem is I addicted to SO and SO sucks my time for hours until I have forgotten that I suppose to continue coding and not browsing the SO site.

My question: How to calculate the total time a user spending on an open application like Firefox?

Update:

I need to play a song as warning message to myself if I stay too long on Firefox. My intent is to create a winform or windows service to achieve this

like image 965
Predator Avatar asked Jun 24 '11 17:06

Predator


1 Answers

This guy, Sateesh Arveti, coded what you are looking for: Active Application Watcher:

Up to now, I have seen so many applications that will show system usage in terms of memory, processor...But, A user don't want this all details. He May expect to know how much time, he is spending on each application like browser, Winamp by the end of day...This application will help out a user to know how much time , he is spending on each application every day. This application assumes that the window, which is active as the application on which the user is working. So, it will log that application details like window title, process name and time spent on it in an xml file. It will continue like that until the application is closed. Once the application is closed, it will show entire active application's details in a browser with proper format.

Here is my simple vb.net version (I added the sound alert event for FireFox).

enter image description here

Create a WinTracker class:

Imports System
Imports System.ComponentModel

Public Class WinTracker
  Implements INotifyPropertyChanged
  Public Event PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
  Public Event SoundAlert(ByVal sender As Object, ByVal e As EventArgs)

  Private _ID As Integer
  Private _Text As String
  Private _ElapsedTime As TimeSpan
  Private _LastStart As DateTime
  Private _RunningTime As TimeSpan

  Public Sub New(ByVal id As Integer, ByVal text As String)
    _ID = id
    _Text = text
    Call StartTracking()
  End Sub

  ReadOnly Property ID() As Integer
    Get
      Return _ID
    End Get
  End Property

  Property Text() As String
    Get
      Return _Text
    End Get
    Set(ByVal value As String)
      If value <> _Text Then
        _Text = value
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Text"))
      End If
    End Set
  End Property

  Public Sub StartTracking()
    _RunningTime = TimeSpan.Zero
    _LastStart = DateTime.Now
  End Sub

  Public Sub StopTracking()
    _ElapsedTime += _RunningTime
    _RunningTime = TimeSpan.Zero
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ToString"))
  End Sub

  Public Sub UpdateTime()
    _RunningTime = (DateTime.Now - _LastStart)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ToString"))

    If _RunningTime.Seconds >= 60 Then
      RaiseEvent SoundAlert(Me, New EventArgs)
    End If
  End Sub

  Public Overrides Function ToString() As String
    Return "(" & FormatTimeSpan(_ElapsedTime + _RunningTime) & ")   " & _Text
  End Function

  Public Shared Operator =(ByVal thisItem As WinTracker, ByVal thatItem As WinTracker) As Boolean
    Return (thisItem.ID = thatItem.ID)
  End Operator

  Public Shared Operator <>(ByVal thisItem As WinTracker, ByVal thatItem As WinTracker) As Boolean
    Return Not (thisItem.ID = thatItem.ID)
  End Operator

  Private Function FormatTimeSpan(ByVal span As TimeSpan) As String
    Return span.Hours.ToString("00") & " hrs " & span.Minutes.ToString("00") & " min " & span.Seconds.ToString("00") & " sec"
  End Function

  Public Shared Sub SwitchWindows(ByVal FromWindow As WinTracker, ByVal ToWindow As WinTracker)
    FromWindow.StopTracking()
    ToWindow.StartTracking()
  End Sub

End Class

And then create a form with a timer and a listbox:

Imports System
Imports System.ComponentModel
Imports System.Diagnostics
Imports System.Runtime.InteropServices

Public Class Form1
  Private Declare Auto Function GetForegroundWindow Lib "user32" () As IntPtr
  Private Declare Auto Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Int32, ByRef lpdwProcessId As Int32) As UInt32

  Private _Windows As New BindingList(Of WinTracker)
  Private _ActiveWindow As WinTracker

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    With ListBox1
      .ValueMember = "ID"
      .DisplayMember = "ToString"
      .DataSource = New BindingSource(_Windows, Nothing)
    End With
    Timer1.Enabled = True
  End Sub

  Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
    Dim hWnd As Integer = GetForegroundWindow().ToInt32

    If hWnd > 0 Then
      Dim id As Integer = 1
      Call GetWindowThreadProcessId(hWnd, id)
      If id > 0 Then
        Dim text As String = Process.GetProcessById(id).ProcessName

        If text <> String.Empty Then
          Dim spent As WinTracker = _Windows.FirstOrDefault(Function(x As WinTracker) x.ID = id)
          If spent Is Nothing Then
            spent = New WinTracker(id, text)
            _Windows.Add(spent)

            If text.ToLower = "firefox" Then
              AddHandler spent.SoundAlert, AddressOf WinTracker_SoundAlert
            End If

          Else
            spent.Text = text
          End If

          If _ActiveWindow Is Nothing Then
            _ActiveWindow = spent
          Else
            If _ActiveWindow <> spent Then
              WinTracker.SwitchWindows(_ActiveWindow, spent)
              _ActiveWindow = spent
            Else
              _ActiveWindow.UpdateTime()
            End If
          End If

        End If
      End If
    End If
  End Sub

  Private Sub WinTracker_SoundAlert(ByVal sender As Object, ByVal e As EventArgs)
    My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)
  End Sub    

End Class

Refactor as needed.

like image 66
LarsTech Avatar answered Sep 25 '22 02:09

LarsTech