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
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).
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.