Active Window Logger

I was curious how I spend my time and wanted something simple to log which window was active on my computer. I couldn't see anything that did this easily on the internet, although there is a (more sophisticated/complicated) browsing history tracker, and I needed to relax for an hour or two so I thought I'd give it a shot in Python and see what came out. After looking at the flashing taskbar icon tutorial, how to get the currently active window, how to detect if Windows is idle and how to get rid of the console window, I could finally start programming. I really don't know how people programmed before Google.

Python really makes things easy. It took less than 90 lines of code and just a couple hours to write this. So here is the code for it if you want to build it yourself:

PYTHON:
  1. import wx
  2. from win32gui import GetWindowText, GetForegroundWindow
  3. from time import sleep, strftime, localtime
  4. from ctypes import windll, Structure, c_uint, sizeof, byref
  5.  
  6. class TaskBarApp(wx.Frame):
  7.     def __init__(self, parent, id, title):
  8.         wx.Frame.__init__(self, parent, -1, title, size = (1, 1), style=wx.FRAME_NO_TASKBAR|wx.NO_FULL_REPAINT_ON_RESIZE)
  9.         self.ICON_STATE = 1
  10.         self.ID_ICON_TIMER=wx.NewId()
  11.         self.tbicon = wx.TaskBarIcon()
  12.         icon = wx.Icon('logon.ico', wx.BITMAP_TYPE_ICO)
  13.         self.tbicon.SetIcon(icon, 'Logging')
  14.         self.tbicon.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarLeftDClick)
  15.         self.tbicon.Bind(wx.EVT_TASKBAR_RIGHT_UP, self.OnTaskBarRightClick)
  16.         self.Bind(wx.EVT_TIMER, self.Log, id=self.ID_ICON_TIMER)
  17.         self.SetIconTimer()
  18.         self.Show(True)
  19.         self.lastInputInfo = self.LASTINPUTINFO()
  20.         self.lastInputInfo.cbSize = sizeof(self.lastInputInfo)
  21.         self.Write(self.Now()+"<|>__LOGGERSTART__<|>0\n")
  22.  
  23.     def OnTaskBarLeftDClick(self, evt):
  24.         if self.ICON_STATE == 0:
  25.             self.Write(self.Now()+"<|>__LOGGERUNPAUSE__<|>0\n")
  26.             self.StartIconTimer()
  27.             icon = wx.Icon('logon.ico', wx.BITMAP_TYPE_ICO)
  28.             self.tbicon.SetIcon(icon, 'Logging')
  29.             self.ICON_STATE = 1
  30.         else:
  31.             self.StopIconTimer()
  32.             self.Write(self.Now()+"<|>__LOGGERPAUSE__<|>0\n")
  33.             icon = wx.Icon('logoff.ico', wx.BITMAP_TYPE_ICO)
  34.             self.tbicon.SetIcon(icon, 'Not Logging')
  35.             self.ICON_STATE = 0
  36.  
  37.     def OnTaskBarRightClick(self, evt):
  38.         self.StopIconTimer()
  39.         self.Write(self.Now()+"<|>__LOGGERSTOP__<|>0\n")
  40.         self.tbicon.Destroy()
  41.         self.Close(True)
  42.         wx.GetApp().ProcessIdle()
  43.        
  44.     def SetIconTimer(self):
  45.         self.icontimer = wx.Timer(self, self.ID_ICON_TIMER)
  46.         self.icontimer.Start(10000)
  47.  
  48.     def StartIconTimer(self):
  49.         try:
  50.             self.icontimer.Start(10000)
  51.         except:
  52.             pass
  53.  
  54.     def StopIconTimer(self):
  55.         try:
  56.             self.icontimer.Stop()
  57.         except:
  58.             pass
  59.  
  60.     def Log(self, evt):
  61.         windll.user32.GetLastInputInfo(byref(self.lastInputInfo))
  62.         idleDelta = float(windll.kernel32.GetTickCount() - self.lastInputInfo.dwTime) / 1000
  63.         self.Write(self.Now()+"<|>"+GetWindowText(GetForegroundWindow())+"<|>"+str(idleDelta)+"\n")
  64.  
  65.     def Write(self, text):
  66.         f=open('log.tmp', 'a')
  67.         f.write (text)
  68.         f.close()
  69.     def Now(self):
  70.         return strftime("%Y-%m-%d %H:%M:%S", localtime())
  71.  
  72.     class LASTINPUTINFO(Structure):
  73.         _fields_ = [("cbSize", c_uint),("dwTime", c_uint)]
  74.  
  75. class MyApp(wx.App):
  76.     def OnInit(self):
  77.         frame = TaskBarApp(None, -1, ' ')
  78.         frame.Center(wx.BOTH)
  79.         frame.Show(False)
  80.         return True
  81.  
  82. def main():
  83.     app = MyApp(0)
  84.     app.MainLoop()
  85.  
  86. if __name__ == '__main__':
  87.     main()

It's not too pretty but it seems to work. If you try it, it should begin putting an entry in log.tmp every ten seconds of 'datetime<|>program title<|>idle time'. Unfortunately, it takes 16 megs of RAM. I guess there's a lot going on in the background in the imported stuff. I think it would be much more efficient if programmed from scratch but I'm no programmer. Also, I would make an .exe for people without Python but the .dll files that would have to go along with it would take up more than 10 megs. Must be all the stuff going on in the background again. So it's inefficient but it would get the job done if you want something quick for a day or two or maybe it could form the base of a more optimized program. Next time I have a little free time, I might write a program to read the log and make a summary.

Oh you'll also need 2 32x32 .ico files called logon.ico and logoff.ico. You can use these or make your own icons.

A logon icon A logoff icon