2011-06-24 50 views
17

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

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

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

更新:

我需要播放一首歌曲作为警告消息自己,如果我留在Firefox太长。我的目的是建立一个winform或Windows服务来实现这一

+0

我在同样的问题! –

+0

@Luis我真的希望你能解决同样的问题后:p –

+0

是的,对不起,是我可怜的英语 –

回答

1

这不是一个编程问题。这是一个纪律问题。我的建议是:

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

对我感到羞耻。我在我的显示器上创建了一个小的“Code it now”便签 – Predator

3

有许多工具来做到这一点像RescueTime等。 。但是你可以使用一些.net代码来快速打开一个近似值。

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

psList = Process.GetProcesses() 

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

+0

获取主动/聚焦窗口的一些技巧:http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/e80405ae-66a6 -4b89-89e9-29e29765dfe5/ – CodingWithSpike

13

这家伙,Sateesh Arveti,编码你在找什么:Active Application Watcher

到现在为止,我已经见过这么多 应用程序,将显示系统在内存方面 使用, 处理器。 ..但是,用户不想要 这一切的细节。他可能会预计到 知道多少时间,他在 每个应用程序的支出像浏览器,Winamp 在一天结束...此应用程序 将帮助用户知道多少时间,他是花在每个每天应用 。此 应用程序假定窗口 作为用户正在工作的应用程序 处于活动状态。因此,它会将 日志中的应用程序详细信息(如 窗口标题,进程名称和时间 )花费在xml文件中。它将继续如此,直到 应用程序关闭。一旦 应用程序关闭,它将显示 整个活动应用程序的详细信息在 浏览器具有适当的格式。

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

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 

重构:

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 

,然后创建一个形式的计时器和一个列表框。

+0

+1,因为这个建议的工具监视什么是活动窗口,而不仅仅是可能被最小化或没有关注的所有运行。 – CodingWithSpike

+0

@LarsTech:我试过你的代码,但没有声音。问题是什么? – Sean

+0

@david montary首先,检查“My.Computer.Audo.PlaySystemSound(Media.SystemSounds.Beep)”实际上是否有效。如果好,那么确保SoundAlert的事件处理程序已连线。在我的例子中,它只会为Firefox启动。 – LarsTech

11

我强烈建议您注册RescueTime

简单的原因是:

  1. 它希望能够得到你问。 (跟踪应用程序的使用,浏览器的使用,区分生产性和非生产性的网页浏览,如果你花费太多时间偷懒等等,会提醒你)
  2. 设置起来非常快(所以你不会浪费更多时间) 。
  3. 它是免费的(所有你需要的东西)。

我写了一个blog post这个工具曾经有多有用。我会在这里总结一下。


这是一个在计算机上安装的程序,用于跟踪一天中某个程序的焦点,然后是一些程序。测量每个应用程序的使用时间,并在使用浏览器时测量您在各个网站上花费的时间。通过控制面板,您可以对每个程序和特定网站进行分类(并将其他网站分组),并让您确定该程序或网站是否与生产性工作相关联,或分散工作(或中性)。默认情况下,它知道各种各样的网站和像Facebook和MSN程序分心,以及其他类似微软的Word和研究网站是生产力 - 但你可以自由地配置所有这一切:

site classification

,你可以参见上文,我列出的社交网站,信使和个人电子邮件网站被列为分散注意力,或从我的工作中分散注意力,我用于工作的程序和网站被列为高效工作。有几个网站从浏览器中分离出来,但访问过的所有其他网站都归类为“Firefox”,这大部分时间是我花费在不同的编程语言和范例上进行在线研究的时间。

该方案需要所有的聚集你的时候,该信息使用电脑花了,然后给了你,你是如何花费你的时间在一天的概述:

dashboard

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

当我休息一下,并决定是非生产性的,我花了大多数时间在FFYa(25分钟)。

这个工具对于反思您在给定的小时,一天,一周或一个月中做了多少工作很有用。通过不同的时间尺度,您可以比较和可视化处于紧张状态的时间,以及您习惯于放松的时间。更好的是,它可以让你为自己设定目标。

Goals

自己决定你如何你的一天,您愿意花懈怠,多少工作,你想要得到完成,甚至编写一个弹出通知,如果你”会告诉你以任何数量的预定方式重新陷入歧途。

Alerts

我最喜欢的部分,是“AFK”探测器。如果你去吃午饭,打个电话,去开会,或者在你的办公桌旁睡觉,程序就会检测到你已经空闲了,并且在你回来分类你正在做的事时给你一个对话而你离开了。这也是完全可定制的,所以它会清楚你离开计算机的时间是否是生产力或分心。

enter image description hereenter image description here

不要相信自己能继续工作?它带有“聚焦时间”功能。在这里,您可以告诉程序您要扣多久,并在此期间,它会阻止您使用已列出的网站和应用程序作为分心。如果你真的不信任自己,你可以做到这一点,以便在你的时间到来之前,不能阻止它们。

focus

我只有这一天,所以我期待着看到我有多么的生产力每天及每周进行比较的一周。由于这是我第一天参加这个活动,所以我非常努力地坚持下来,因为我对自己在做什么感到自我意识,但是我很好奇,看到一旦我停止关注它,平均会达到什么样的平均水平。我知道我通常会浪费很多时间与Trillian上的人聊天,并浏览FFYa,而不是像我今天所做的那样。收集更多人口统计信息时,我会张贴一些照片。

哦,是的,基本的个人账户是免费的,你可以选择直接连接到你的Google登录(我曾这么做)。

沉迷于自己的工作习惯!


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

这就是说,我在这里,在工作中回答你的问题。 :p

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应用程序,然后加入从工具箱,它被命名为代码中的“定时器1”一“定时器”组件,并且是默认名称。

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

相关问题