Buenas,
Entre ayer y hoy se me dió por crear una pequeña tool que ni bien iniciada se minimiza al trayicon, y luego va "cronometrando" el tiempo que se pasa en una ventana. El registro lo guarda o bien en formato de texto (esta "hardcodeado" el formato), o bien en XML.
Para que se hagan una idea, el XML es más o menos así;
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfWatchedWindow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<WatchedWindow>
<Executable>c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe</Executable>
<ProcessId>5492</ProcessId>
<WindowText>WinWatcher (Running) - Microsoft Visual Studio</WindowText>
<ElapsedTime>00:00:01</ElapsedTime>
</WatchedWindow>
<WatchedWindow>
<Executable>C:\Program Files (x86)\Google\Chrome\Application\chrome.exe</Executable>
<ProcessId>6048</ProcessId>
<WindowText>(37) Twitter - Google Chrome</WindowText>
<ElapsedTime>00:00:16</ElapsedTime>
</WatchedWindow>
<WatchedWindow>
<Executable>C:\Program Files (x86)\Google\Chrome\Application\chrome.exe</Executable>
<ProcessId>6048</ProcessId>
<WindowText>Foro de elhacker.net - Índice - Google Chrome</WindowText>
<ElapsedTime>00:01:13</ElapsedTime>
</WatchedWindow>
<WatchedWindow>
<Executable>C:\Program Files (x86)\Windows Media Player\wmplayer.exe</Executable>
<ProcessId>6276</ProcessId>
<WindowText>Reproductor de Windows Media</WindowText>
<ElapsedTime>00:00:03</ElapsedTime>
</WatchedWindow>
</ArrayOfWatchedWindow>
La jerarquía en base a la cual se cronometran las ventanas es justamente la que se ve en el XML;
Ejecutable > PID de proceso > Texto de ventana
Existen dos momentos en los que se vuelcan los datos a archivo;
- Cada 15 minutos
- Al cerrar la aplicación
Con click derecho en el icono del trayicon se puede cambiar la configuración y ver el log actual sin necesidad del volcado :)
Descarga de código fuente: http://bit.ly/WinWatcher (C# Visual Express 2010)
Le quería dar un uso personal, pero tal vez luego le haga alguna mejora y/o refactoring de código, porque se por ejemplo que tiene un bug conocido, si en un navegador se cambia de pestaña no se refleja hasta bien no se minimize y vuelva a restaurar la ventana, y esto es porque preferí hookear el cambio de ventana en lugar de hacer polling con un timer, así que al cambiar de tab no se entera :-X
Cualquier consulta y/o comentario ya saben
Saludos
Bastante interesante, como con un simple StopWatcher y una idea se puede llegar a una aplicación, lo voy a tener un día activo para ver los tiempos por curiosidad :silbar: Aunque es obvio que el mayor uso es los compiladores :xD de Visual Studio y el Dev.
Cita de: Novlucker en 2 Diciembre 2012, 00:43 AM
Buenas,
Entre ayer y hoy se me dió por crear una pequeña tool que ni bien iniciada se minimiza al trayicon, y luego va "cronometrando" el tiempo que se pasa en una ventana. El registro lo guarda o bien en formato de texto (esta "hardcodeado" el formato), o bien en XML.
Para que se hagan una idea, el XML es más o menos así;
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfWatchedWindow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<WatchedWindow>
<Executable>c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe</Executable>
<ProcessId>5492</ProcessId>
<WindowText>WinWatcher (Running) - Microsoft Visual Studio</WindowText>
<ElapsedTime>00:00:01</ElapsedTime>
</WatchedWindow>
<WatchedWindow>
<Executable>C:\Program Files (x86)\Google\Chrome\Application\chrome.exe</Executable>
<ProcessId>6048</ProcessId>
<WindowText>(37) Twitter - Google Chrome</WindowText>
<ElapsedTime>00:00:16</ElapsedTime>
</WatchedWindow>
<WatchedWindow>
<Executable>C:\Program Files (x86)\Google\Chrome\Application\chrome.exe</Executable>
<ProcessId>6048</ProcessId>
<WindowText>Foro de elhacker.net - Índice - Google Chrome</WindowText>
<ElapsedTime>00:01:13</ElapsedTime>
</WatchedWindow>
<WatchedWindow>
<Executable>C:\Program Files (x86)\Windows Media Player\wmplayer.exe</Executable>
<ProcessId>6276</ProcessId>
<WindowText>Reproductor de Windows Media</WindowText>
<ElapsedTime>00:00:03</ElapsedTime>
</WatchedWindow>
</ArrayOfWatchedWindow>
La jerarquía en base a la cual se cronometran las ventanas es justamente la que se ve en el XML; Ejecutable > PID de proceso > Texto de ventana
Existen dos momentos en los que se vuelcan los datos a archivo;
- Cada 15 minutos
- Al cerrar la aplicación
Con click derecho en el icono del trayicon se puede cambiar la configuración y ver el log actual sin necesidad del volcado :)
Descarga de código fuente: http://bit.ly/WinWatcher (C# Visual Express 2010)
Le quería dar un uso personal, pero tal vez luego le haga alguna mejora y/o refactoring de código, porque se por ejemplo que tiene un bug conocido, si en un navegador se cambia de pestaña no se refleja hasta bien no se minimize y vuelva a restaurar la ventana, y esto es porque preferí hookear el cambio de ventana en lugar de hacer polling con un timer, así que al cambiar de tab no se entera :-X
Cualquier consulta y/o comentario ya saben
Saludos
esta interesante, estudiare el fuente
Ahora tengo una versión recortada (lite), 0% configurable y con una implementación bastante más rústica pero que cumple con lo que necesito :)
MainForm => 00:00:02
Nuevos temas no leídos - Google Chrome => 00:00:12
Twitter - Google Chrome => 00:00:01
Google Reader (193) - Google Chrome => 00:00:01
WinWatcherLite (Running) - Microsoft Visual Studio => 00:00:02
Y cuando digo que está recortada, realmente lo está :P
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Timers;
namespace WinWatcherLite
{
public partial class MainForm : Form
{
string startTime;
string lastWindow;
string logFolder;
Dictionary<string, Stopwatch> windowLog;
public MainForm()
{
InitializeComponent();
InitializeCustomObjects();
}
private void InitializeCustomObjects()
{
startTime = DateTime.Now.ToString("ddMMyyyy_hhmmss");
lastWindow = string.Empty;
logFolder = Path.GetDirectoryName(Application.ExecutablePath);
windowLog = new Dictionary<string, Stopwatch>();
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 500;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
System.Timers.Timer t = new System.Timers.Timer(60000);
t.Elapsed += new ElapsedEventHandler(OnTimedEvent);
t.Start();
}
#region user32.dll
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);
#endregion
public void GetActiveWindow()
{
IntPtr win = GetForegroundWindow();
StringBuilder sb = new StringBuilder(255);
GetWindowText(win, sb, 256);
string currentWindow = sb.ToString();
if (lastWindow != currentWindow)
{
if (windowLog.ContainsKey(lastWindow))
windowLog[lastWindow].Stop();
if (windowLog.ContainsKey(currentWindow))
windowLog[currentWindow].Start();
else
{
Stopwatch sw = new Stopwatch();
sw.Start();
windowLog.Add(currentWindow, sw);
}
lastWindow = currentWindow;
}
}
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
WriteLog();
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
WriteLog();
}
private void timer_Tick(object sender, EventArgs e)
{
GetActiveWindow();
}
private void WriteLog()
{
string filePath = Path.Combine(logFolder, string.Format("WindowLog_{0}.txt", startTime));
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, Stopwatch> registry in windowLog)
{
TimeSpan ts = registry.Value.Elapsed;
string elapsedTime = string.Format("{0:00}:{1:00}:{2:00}", ts.Hours, ts.Minutes, ts.Seconds);
sb.AppendLine(string.Format("{0} => {1}", registry.Key, elapsedTime));
}
using (StreamWriter sw = new StreamWriter(filePath))
sw.Write(sb.ToString());
}
}
}
Saludos