WinWatcher (WinForms Application Source)

Iniciado por Novlucker, 2 Diciembre 2012, 00:43 AM

0 Miembros y 1 Visitante están viendo este tema.

Novlucker

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í;

Código (xml) [Seleccionar]
<?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
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

Keyen Night

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.
La Fé Mueve Montañas...
                                    ...De Dinero

La programación es más que un trabajo es más que un hobby es una pasión...

spiritdead

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í;

Código (xml) [Seleccionar]
<?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
Facilitador De Tareas - Task Simplifier (FDT)

Novlucker

#3
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
Código (csharp) [Seleccionar]
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
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein