Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Idea: Keep track of how long an application has run


  • Please log in to reply
12 replies to this topic
anil_robo
  • Members
  • 17 posts
  • Last active: Jul 08 2014 04:32 PM
  • Joined: 08 May 2008
I think I'm gaming too much these days and I'd like to keep track of my gaming time. I want an application/script that will tell me how long a game (an .exe file) has been active on my computer. If I'm idle for more than 1 min, the timer should stop, and will resume when I make activity on the keyboard. If the active game window loses focus (e.g. when I alt+tab to check my email in the browser), the timer should also pause.

Is this possible in autohotkey?

Thanks in anticipation.

BoBo³
  • Guests
  • Last active:
  • Joined: --

Is this possible in autohotkey?

Yes.

anil_robo
  • Members
  • 17 posts
  • Last active: Jul 08 2014 04:32 PM
  • Joined: 08 May 2008
Windows keeps track of how long an application/process has run. I'm thinking if ahk can just get the data from windows program manager.

However ...

I looked at the commands list. There doesn't seem to be a command which can tell instantly how long a windows process/application has been running. The other method is that the ahk script runs in the background, and keeps polling the active applications and builds a "database". This database can later be analyzed to see how long a given application has run.

Is this the right way of thinking about it? Thanks.

BoBo³
  • Guests
  • Last active:
  • Joined: --

Is this the right way of thinking about it?

Yes.

anil_robo
  • Members
  • 17 posts
  • Last active: Jul 08 2014 04:32 PM
  • Joined: 08 May 2008
Okay I dabbled for a few hours and here it is:


;The Name of the game window must start with the specified name
SetTitleMatchMode, 1

;Number format set to 10 digits with one decimal point
SetFormat, Float, 10.1

;Start the timer value at t=0
t = 0

;Display the time info on the desktop
Progress, b w300 x0 y0, , Moto Racer played for %t% seconds,

;Start the timer function at 100ms intervals and let it be "persistent".
#Persistent
SetTimer, Findgame, 100

;Find the game window by its title, and advance time by 0.1 seconds each time it's found.
Findgame:
IfWinExist, Moto Racer - © 1997
{
t := t+0.1
Progress, , , %t% seconds,
}
Else
Goto, Findgame

So it works.

However, there is another thing I'd like it to do. I want the script to make a log file that will keep entries of all the game time. I'm not very proficient with autohotkey as yet, so I was trying to think of "onExit" command. However, it didn't work the way I wanted. Here is what I did, but it doesn't work:

SetTitleMatchMode, 1
SetFormat, Float, 10.1

t = 0
Progress, b w300 x0 y0, , Moto Racer played for %t% seconds,

#Persistent
SetTimer, Findgame, 100
OnExit, Log

Findgame:
IfWinExist, Moto Racer - © 1997
{
t := t+0.1
Progress, , , %t% seconds,
}
Else
Goto, Findgame

Log:
FileAppend, Time %A_Now% = %t% seconds, c:\gameslog.txt

Any idea what's wrong?

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
First off, you need an ExitApp command at the end of the Log subroutine if you want to exit the program.

IMPORTANT: Since the specified subroutine is called instead of terminating the script, that subroutine must use the ExitApp command if termination is desired.


Does this fix the problem, or was there something else wrong?

Log: 
FileAppend, Time %A_Now% = %t% seconds, c:\gameslog.txt
[color=red]ExitApp[/color]


  • Guests
  • Last active:
  • Joined: --
is this an option?:

var := 0

loop
{
    ifwinexist, [gamewindowname]
    {
        var := %var% + 1
    }
    else
    {
        run [a text file]
        send %var%
        send ^s ;saves the file
        winkill, [textfile window name]
    }
    sleep, 1000 ; repeat the loop every second
}


Lexikos
  • Administrators
  • 9445 posts
  • Last active: Sep 15 2014 04:01 PM
  • Joined: 17 Oct 2006
Guest's code has three problems that I can see:
[*:3gv76nmi]Incorrect use of %percent% signs in an expression.
[*:3gv76nmi]It increments by one each iteration, but since each iteration will take slightly longer than 1 second, it becomes less accurate the longer it runs.
[*:3gv76nmi]It automates a text editor (presuming that is the default action for text files) rather than using the much more reliable FileAppend method.There are cleaner ways than timers to detect window activation. For instance,
; The active window may be hidden. One example of this is when Menu,..,Show
; is used, as it activates the main AutoHotkey window (which owns the menu).
DetectHiddenWindows, On
Loop {
    ActiveBegin := A_TickCount
    [color=darkred]WinGetActiveTitle, ActiveTitle[/color]
    ; Wait for some other window to be activated.
    WinWaitNotActive, % "ahk_id " . WinActive("A")
    ; Calculate how long it was active for.
    ActiveTime := A_TickCount - ActiveBegin
    ; Log the title and duration of the active window.
    FileAppend, %ActiveTitle% was active for %ActiveTime%ms`n, log.txt
}
Of course, you may extend it to check the window title before logging. (Edit: Fixed.)

First off, you need an ExitApp command at the end of the Log subroutine if you want to exit the program.

I think anil_robo wants to detect exit of the game, so OnExit is inappropriate to begin with.

anil_robo
  • Members
  • 17 posts
  • Last active: Jul 08 2014 04:32 PM
  • Joined: 08 May 2008
It would be great if Autohotkey can detect exit of a game. I don't know how to do this though, so I'm using a workaround (find the game window, and when the window is no longer found, consider the game has exited).

I worked on this for a few more hours and here is the result:

#Persistent
FormatTime, time, , Longdate

Menu, Tray, NoStandard
Menu, Tray, Tip, Game Time Logger
Menu, tray, add, Exit, Exit

Gui +owner +AlwaysonTop
Gui, Add, Text, vmytext x16 y27 w300 h240 , No game running.
Gui, Show, w300, Game Time Calculator

;The Name of the game window must start with the specified name
SetTitleMatchMode, 1

;Number format set to one decimal point
SetFormat, Float, 0.1

;Start the timer value at t=0
t1 = 0
t2 = 0

;Set default game name to "Nothing"
g1 = Nothing
g2 = Nothing

;Start the timer function at 500ms intervals.
SetTimer, Findgame, 500

;Find the game window, and advance time by 0.5 seconds each time it's found.
Findgame:

;FIND MOTO RACER
;========================================================
if WinExist("Moto Racer - © 1997" "ahk_class DirectDraw")
{
g1 = "Moto Racer"
	{
	t1 := t1+0.5
guicontrol,,mytext, %g1% played for %t1% seconds. 
	return
	}
}
Else
{
If t1 > 0.5
	{
	FileAppend, %time% %g1% played for %t1% seconds `n, c:\gameslog.txt
	t1 = 0
	}
}

;FIND ROAD RASH
;========================================================
If WinExist("Road Rash" "ahk_class RashRoot")
{
g2 = "Road Rash"
	{
	t2 := t2+0.5
guicontrol,,mytext, %g2% played for %t2% seconds. 
	return
	}
}
Else
{
If t2 > 0.5
	{
	FileAppend, %time% %g2% played for %t2% seconds `n, c:\gameslog.txt
	t2 = 0
	}
}

;LOOP AGAIN
;=======================================================
Goto, Findgame

Exit:
ExitApp

It does the job well, for these two games. I'm going to add more games (and more functions) soon.

However I have a question. Because I don't have a programming background, I think my script is not very "efficient". Any suggestions?

Lexikos
  • Administrators
  • 9445 posts
  • Last active: Sep 15 2014 04:01 PM
  • Joined: 17 Oct 2006

I think my script is not very "efficient". Any suggestions?

My previous post... If that is not appropriate, use a shell hook to detect window creation/destruction.

anil_robo
  • Members
  • 17 posts
  • Last active: Jul 08 2014 04:32 PM
  • Joined: 08 May 2008
Hmm I just learned something new in Autohotkey. I tried Lexikos' script, and I think it's far cleaner and accurate than what I was trying to do. However, it's not reporting the window name accurately. When I start playing a game, it reports game time only a few milliseconds, and then the rest of the time is added to the last active window. For example let's say I click start menu and start a game. I play the game for 30,000 ms. The script output will show the game active for 100 ms and "start menu" active for 29,900 ms.

I would really like to carry forward Lexikos' idea, if somebody can tell me why it's recording the incorrect window name? Thanks!

Lexikos
  • Administrators
  • 9445 posts
  • Last active: Sep 15 2014 04:01 PM
  • Joined: 17 Oct 2006
Whoops, WinGetActiveTitle was in the wrong place. I've updated the code.

autohost
  • Members
  • 1 posts
  • Last active: Jan 17 2011 02:21 AM
  • Joined: 17 Jan 2011

Hmm I just learned something new in Autohotkey. I tried Lexikos' script, and I think it's far cleaner and accurate than what I was trying to do. However, it's not reporting the window name accurately. When I start playing a game, it reports game time only a few milliseconds, and then the rest of the time is added to the last active window. For example let's say I click start menu and start a game. I play the game for 30,000 ms. The script output will show the game active for 100 ms and "start menu" active for 29,900 ms.

I would really like to carry forward Lexikos' idea, if somebody can tell me why it's recording the incorrect window name? Thanks!

The ActiveBegin := A_TickCount line needs to be above the Loop, not inside it.