实现一个简单的DeskTime

最近发现DeskTime是一个不错的app,可以帮助监控自己的时间去哪里了,以及效率值,碎片化等等,有兴趣可以去点点

A Time Tracker App For Businesses & Freelancers | DeskTime

但是这东西需要付费,也没啥技术含量呀。

于是想着用C#写一个

这里就先讲讲思路

主要的功能拆分

  • 监控前置窗口
  • 监控idle,比如窗口前置,但人走开一段时间了,肯定不能算
  • 图表绘制

先看怎么获取前置窗口

private static string GetActiveWindowTitle()
    {
        // 获取当前活动窗口的标题
        IntPtr hWnd = GetForegroundWindow();
        StringBuilder titleBuilder = new StringBuilder(256);
        GetWindowText(hWnd, titleBuilder, titleBuilder.Capacity);
        return titleBuilder.ToString();
    }


    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

运行就可以获得前置窗口的标题了,比如

Title '写文章-CSDN创作中心 - Google Chrome'

但是像一些进程会修改title,从而造成无法识别是啥东西,我们需要同时判断一下进程id,就比较稳了,方法如下

    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
   
public static string GetProcessName(IntPtr foregroundWindowHandle)
    {
        try
        {
            uint processId;
            GetWindowThreadProcessId(foregroundWindowHandle, out processId);

            // 通过进程ID获取进程信息
            Process process = Process.GetProcessById((int)processId);
            return process.ProcessName;
        }
        catch
        {

        }

        return "unknown";

    }

优化后的结果如下

Title '新加卷 (F:)' process=explorer

然后是如何获取idle时间


    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

    [StructLayout(LayoutKind.Sequential)]
    struct LASTINPUTINFO
    {
        public uint cbSize;
        public int dwTime;
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern uint GetTickCount();
    private static uint GetLastInputTime()
    {
        LASTINPUTINFO lii = new LASTINPUTINFO();
        lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));

        if (GetLastInputInfo(ref lii))
        {
            // dwTime is the tick count when the last input event was received
            uint lastInputTick = (uint)Environment.TickCount - (uint)lii.dwTime;
            return lastInputTick;
        }
        else
        {
            // Error handling
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
        }
    }

通过GetLastInputTime可以获取上次操作(鼠标键盘事件)到当前的时间ms数。

我们就可以很容易通过差值计算出非活跃时间了

分类

现在我们通过采集,可以获得主窗口标题和进程名两个信息,然后要做的就是做标题聚合

其实就是吧两个属性合并成一个最后分类使用的string

private static string Convert(string title, string processName)
{
    if (processName.Contains("chrome"))
    {
        else if (title.Contains("csdn"))
            return "csdn";
        else if (title.Contains("百度"))
            return "百度";
        else if (title.Contains("bilibili"))
            return "bilibili";
        else if (title.Contains("lockapp"))
            return "idle";

        return title;
    }
    else
    {
        if (title.Contains("microsoft visual studio"))
            return "vss";
        else if (title.Contains("visual studio code"))
            return "vscode";
        else if (title.Contains("记事本"))
            return "记事本";
        return processName;
    }
}

图表绘制

搞个插件画一下,应该不成问题

最后的效果如图,和desktime差别不大吧

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值