如何计算用户在应用程序上花费的总时间?

时间:2011-06-24 17:45:22

标签: .net vb.net

我想创建一个能够计算用户(即我自己)在特定应用程序上花费的总时间的应用程序,例如Firefox。如果用户在Firefox上花费了大量时间(例如1小时或更长时间),此应用程序应显示警告消息

原因:我是VB.NET开发人员。在我的工作时间,我的主要工具是Visual Studio,我想要编码。但我偶尔需要Firefox来访问互联网(特别是SO和其他网站),以便为我的编程问题寻找解决方案。问题是我沉迷于SO而且糟透了我几个小时的时间,直到我忘记了我想继续编码而不是浏览SO网站。

我的问题:如何计算用户在Firefox等开放应用上花费的总时间?

更新

如果我在Firefox上停留太长时间,我需要向自己播放一首歌作为警告信息。我的目的是创建一个winform或windows服务来实现这个目标

6 个答案:

答案 0 :(得分:13)

这个人Sateesh Arveti编码了你要找的东西:Active Application Watcher

  

到目前为止,我见过很多   将显示系统的应用程序   在记忆方面的用法,   处理器...但是,用户不想要   这一切细节。他可以期待   知道他花了多少时间   每个应用程序,如浏览器,Winamp   到一天结束......这个应用程序   将帮助用户知道多少   时间,他在每个人身上花钱   每天申请。这个   应用程序假定窗口,   它作为应用程序处于活动状态   用户正在工作。所以,它会   记录该应用程序详细信息   窗口标题,进程名称和时间   花在它上面的xml文件中。它会   继续这样直到   申请已结束。一旦   应用程序已关闭,它将显示   整个活动应用程序的详细信息   格式正确的浏览器。

这是我简单的vb.net版本(我为FireFox添加了声音警报事件)。

enter image description here

创建一个WinTracker类:​​

Imports System
Imports System.ComponentModel

Public Class WinTracker
  Implements INotifyPropertyChanged
  Public Event PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
  Public Event SoundAlert(ByVal sender As Object, ByVal e As EventArgs)

  Private _ID As Integer
  Private _Text As String
  Private _ElapsedTime As TimeSpan
  Private _LastStart As DateTime
  Private _RunningTime As TimeSpan

  Public Sub New(ByVal id As Integer, ByVal text As String)
    _ID = id
    _Text = text
    Call StartTracking()
  End Sub

  ReadOnly Property ID() As Integer
    Get
      Return _ID
    End Get
  End Property

  Property Text() As String
    Get
      Return _Text
    End Get
    Set(ByVal value As String)
      If value <> _Text Then
        _Text = value
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Text"))
      End If
    End Set
  End Property

  Public Sub StartTracking()
    _RunningTime = TimeSpan.Zero
    _LastStart = DateTime.Now
  End Sub

  Public Sub StopTracking()
    _ElapsedTime += _RunningTime
    _RunningTime = TimeSpan.Zero
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ToString"))
  End Sub

  Public Sub UpdateTime()
    _RunningTime = (DateTime.Now - _LastStart)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ToString"))

    If _RunningTime.Seconds >= 60 Then
      RaiseEvent SoundAlert(Me, New EventArgs)
    End If
  End Sub

  Public Overrides Function ToString() As String
    Return "(" & FormatTimeSpan(_ElapsedTime + _RunningTime) & ")   " & _Text
  End Function

  Public Shared Operator =(ByVal thisItem As WinTracker, ByVal thatItem As WinTracker) As Boolean
    Return (thisItem.ID = thatItem.ID)
  End Operator

  Public Shared Operator <>(ByVal thisItem As WinTracker, ByVal thatItem As WinTracker) As Boolean
    Return Not (thisItem.ID = thatItem.ID)
  End Operator

  Private Function FormatTimeSpan(ByVal span As TimeSpan) As String
    Return span.Hours.ToString("00") & " hrs " & span.Minutes.ToString("00") & " min " & span.Seconds.ToString("00") & " sec"
  End Function

  Public Shared Sub SwitchWindows(ByVal FromWindow As WinTracker, ByVal ToWindow As WinTracker)
    FromWindow.StopTracking()
    ToWindow.StartTracking()
  End Sub

End Class

然后使用计时器和列表框创建一个表单:

Imports System
Imports System.ComponentModel
Imports System.Diagnostics
Imports System.Runtime.InteropServices

Public Class Form1
  Private Declare Auto Function GetForegroundWindow Lib "user32" () As IntPtr
  Private Declare Auto Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Int32, ByRef lpdwProcessId As Int32) As UInt32

  Private _Windows As New BindingList(Of WinTracker)
  Private _ActiveWindow As WinTracker

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    With ListBox1
      .ValueMember = "ID"
      .DisplayMember = "ToString"
      .DataSource = New BindingSource(_Windows, Nothing)
    End With
    Timer1.Enabled = True
  End Sub

  Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
    Dim hWnd As Integer = GetForegroundWindow().ToInt32

    If hWnd > 0 Then
      Dim id As Integer = 1
      Call GetWindowThreadProcessId(hWnd, id)
      If id > 0 Then
        Dim text As String = Process.GetProcessById(id).ProcessName

        If text <> String.Empty Then
          Dim spent As WinTracker = _Windows.FirstOrDefault(Function(x As WinTracker) x.ID = id)
          If spent Is Nothing Then
            spent = New WinTracker(id, text)
            _Windows.Add(spent)

            If text.ToLower = "firefox" Then
              AddHandler spent.SoundAlert, AddressOf WinTracker_SoundAlert
            End If

          Else
            spent.Text = text
          End If

          If _ActiveWindow Is Nothing Then
            _ActiveWindow = spent
          Else
            If _ActiveWindow <> spent Then
              WinTracker.SwitchWindows(_ActiveWindow, spent)
              _ActiveWindow = spent
            Else
              _ActiveWindow.UpdateTime()
            End If
          End If

        End If
      End If
    End If
  End Sub

  Private Sub WinTracker_SoundAlert(ByVal sender As Object, ByVal e As EventArgs)
    My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)
  End Sub    

End Class

根据需要重构。

答案 1 :(得分:11)

我强烈建议您注册RescueTime

原因很简单:

  1. 确实想要你问过。 (跟踪应用程序的使用,浏览器的使用,区分生产性和非生产性的Web浏览,如果您花费太多时间懈怠,请提醒您,等等。)
  2. 设置速度极快(所以你不会浪费更多时间)。
  3. 它是免费的(对于你需要的所有东西)。
  4. 我写了一篇关于这个工具曾经有用的blog post。我在这里总结一下。


    这是您在计算机上安装的程序,用于跟踪程序在一天中关注的内容,然后是一些程序。测量每个应用程序的使用时间,并且在使用浏览器时,还会测量您在各个网站上花费的时间。使用控制面板,您可以对每个程序和特定网站进行分类(并将其他网站组合在一起),并让您确定该程序或网站是与生产性工作相关联,还是分散工作(或中立)。默认情况下,它知道各种网站和程序,如Facebook和MSN分散注意力,而像Microsoft Word和研究网站这样的其他网站是高效的 - 但你可以自由配置所有这些:

    site classification

    正如您在上面所看到的,我有社交网站,信使和个人电子邮件网站被列为分散注意力或分散我工作的注意力,我用于工作的程序和网站被列为高效工作。有几个网站与浏览分开,但访问过的所有其他网站都归入“Firefox”,这主要是我花在不同编程语言和范例上进行在线研究的时间。

    该程序会收集有关您使用计算机所花费时间的所有信息,然后概述您如何在一天中花费时间:

    dashboard

    这些表明我每隔几个小时花费15分钟做一些工作以外的事情。当我工作的时候,你可以看到我花了3个小时在网上做研究,大约2.5个人做软件开发,45分钟做商业电子邮件等等。

    当休息一下并决定无效时,我花了大部分时间在FFYa(25分钟)。

    此工具非常适合反映您在给定的小时,天,周或月中完成的工作量。不同的时间尺度让您可以比较和可视化您处于紧缩状态的时间,以及您习惯于懈怠的时间。更好的是,它可以让你为自己设定目标。

    Goals

    自己决定你愿意花多少时间懈怠,想要完成多少工作,甚至编制弹出通知,告诉你是否在任何数字上误入歧途预定的方式。

    Alerts

    我最喜欢的部分之一是“AFK”探测器。如果你去吃午饭,打个电话,去参加会议,或者在你的办公桌上睡着,程序会发现你已经闲着并在你回来时给你一个对话来分类你在做什么当你离开的时候。这也是完全可定制的,因此它将弄清楚您离开计算机的时间是否有效或分散注意力。

    enter image description here enter image description here

    不相信自己继续工作?它具有“焦点时间”功能。在这里,您可以告诉程序您想要缩短和工作多长时间,在此期间,它将阻止您使用您列出的令人分心的网站和应用程序。如果你真的不相信自己,你可以做到这一点,以便在你的时间到来之前你不能解锁它们。

    focus

    我只有一天,所以我期待看到我的生产力如何比较每天和每周。因为这是我第一天用它,所以我非常努力,因为我自我意识到我在做什么,但我很好奇,一旦我不再注意它,它会看到它的平均值是什么样的。我知道我通常会浪费很多时间与Trillian上的人聊天并浏览FFYa,而不是今天我所做的。我会在收集更多人口统计数据时发布一些图片。

    哦,是的,基本的个人帐户是免费的,您可以选择将其直接链接到您的Google登录(我做过)。

    欣赏自己的工作习惯!


    我个人不再使用它了。我发现,对我而言,我只能通过这种自我改进和统计游戏来激发这么多的生产力。更好的长期解决方案是找到比Skeptics Exchange上最新热门话题更有趣的工作。

    话虽如此,我在这里,在工作中回答你的问题。 :P

答案 2 :(得分:5)

这几乎是WinForms应用程序执行此操作的完整源代码。请注意,它只会增加Firefox有焦点的时间。

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace FireFoxWatch
{
  public partial class Form1 : Form
  {
    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll", SetLastError = true)]
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    private TimeSpan fireFoxElapsedTime = new TimeSpan();

    public Form1()
    {
      InitializeComponent();
    }

    // this handler is called each time the Timer component's interval is reached.
    private void timer1_Tick(object sender, EventArgs e)
    {
      var wnd = GetForegroundWindow();
      uint procId;
      GetWindowThreadProcessId(wnd, out procId);

      var process = Process.GetProcessById((int)procId);
      if (process.ProcessName.Equals("firefox", StringComparison.CurrentCultureIgnoreCase))
        fireFoxElapsedTime += new TimeSpan(0, 0, 0, 0, timer1.Interval);

      //TODO: If fireFoxElapsedTime > Some predetermined TimeSpan, play a sound.
      // Right now it just updates a display label.
      label1.Text = fireFoxElapsedTime.ToString();
    }

    // start the timer when the form loads.
    private void Form1_Load(object sender, EventArgs e)
    {
      timer1.Start();
    }
  }
}

此处未显示的唯一部分是我创建了一个默认的WinForms应用程序,然后在工具箱中添加了一个“Timer”组件,在代码中名为“timer1”,并且是默认名称。

以上代码只是更新winform标签上的总时间,但您可以轻松添加代码来播放声音。

答案 3 :(得分:3)

有许多工具可以像RescueTime那样执行此操作......但是你可以使用一些.net代码来快速敲定近似值。

您需要在某个给定的时间间隔内轮询进程列表

psList = Process.GetProcesses() 

您可以使用starttime属性和主窗口标题来获取有关每个进程的信息。我不知道如何判断哪一个是活跃的。

答案 4 :(得分:2)

可能你应该尝试使用firefox附加组件,
这是链接https://addons.mozilla.org/en-US/firefox/addon/timetracker/

答案 5 :(得分:1)

这不是编程问题。这是一门学科问题。我的建议:

  1. 首先,不要依赖申请来告诉你该怎么做。
  2. 其次,应用程序可以警告您,但最终您可以禁用它,将其关闭。
  3. 第三,我对你真正的问题的建议,即没有纪律和不良的职业道德,就是在你的监视器前放置一个小横幅,上面写着“专注于你的工作”或“现在编码”或“这是邪恶的