我想创建一个能够计算用户(即我自己)在特定应用程序上花费的总时间的应用程序,例如Firefox。如果用户在Firefox上花费了大量时间(例如1小时或更长时间),此应用程序应显示警告消息
原因:我是VB.NET开发人员。在我的工作时间,我的主要工具是Visual Studio,我想要编码。但我偶尔需要Firefox来访问互联网(特别是SO和其他网站),以便为我的编程问题寻找解决方案。问题是我沉迷于SO而且
我的问题:如何计算用户在Firefox等开放应用上花费的总时间?
更新
如果我在Firefox上停留太长时间,我需要向自己播放一首歌作为警告信息。我的目的是创建一个winform或windows服务来实现这个目标
答案 0 :(得分:13)
这个人Sateesh Arveti编码了你要找的东西:Active Application Watcher:
到目前为止,我见过很多 将显示系统的应用程序 在记忆方面的用法, 处理器...但是,用户不想要 这一切细节。他可以期待 知道他花了多少时间 每个应用程序,如浏览器,Winamp 到一天结束......这个应用程序 将帮助用户知道多少 时间,他在每个人身上花钱 每天申请。这个 应用程序假定窗口, 它作为应用程序处于活动状态 用户正在工作。所以,它会 记录该应用程序详细信息 窗口标题,进程名称和时间 花在它上面的xml文件中。它会 继续这样直到 申请已结束。一旦 应用程序已关闭,它将显示 整个活动应用程序的详细信息 格式正确的浏览器。
这是我简单的vb.net版本(我为FireFox添加了声音警报事件)。
创建一个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
原因很简单:
我写了一篇关于这个工具曾经有用的blog post。我在这里总结一下。
这是您在计算机上安装的程序,用于跟踪程序在一天中关注的内容,然后是一些程序。测量每个应用程序的使用时间,并且在使用浏览器时,还会测量您在各个网站上花费的时间。使用控制面板,您可以对每个程序和特定网站进行分类(并将其他网站组合在一起),并让您确定该程序或网站是与生产性工作相关联,还是分散工作(或中立)。默认情况下,它知道各种网站和程序,如Facebook和MSN分散注意力,而像Microsoft Word和研究网站这样的其他网站是高效的 - 但你可以自由配置所有这些:
正如您在上面所看到的,我有社交网站,信使和个人电子邮件网站被列为分散注意力或分散我工作的注意力,我用于工作的程序和网站被列为高效工作。有几个网站与浏览分开,但访问过的所有其他网站都归入“Firefox”,这主要是我花在不同编程语言和范例上进行在线研究的时间。
该程序会收集有关您使用计算机所花费时间的所有信息,然后概述您如何在一天中花费时间:
这些表明我每隔几个小时花费15分钟做一些工作以外的事情。当我工作的时候,你可以看到我花了3个小时在网上做研究,大约2.5个人做软件开发,45分钟做商业电子邮件等等。
当休息一下并决定无效时,我花了大部分时间在FFYa(25分钟)。
此工具非常适合反映您在给定的小时,天,周或月中完成的工作量。不同的时间尺度让您可以比较和可视化您处于紧缩状态的时间,以及您习惯于懈怠的时间。更好的是,它可以让你为自己设定目标。
自己决定你愿意花多少时间懈怠,想要完成多少工作,甚至编制弹出通知,告诉你是否在任何数字上误入歧途预定的方式。
我最喜欢的部分之一是“AFK”探测器。如果你去吃午饭,打个电话,去参加会议,或者在你的办公桌上睡着,程序会发现你已经闲着并在你回来时给你一个对话来分类你在做什么当你离开的时候。这也是完全可定制的,因此它将弄清楚您离开计算机的时间是否有效或分散注意力。
不相信自己继续工作?它具有“焦点时间”功能。在这里,您可以告诉程序您想要缩短和工作多长时间,在此期间,它将阻止您使用您列出的令人分心的网站和应用程序。如果你真的不相信自己,你可以做到这一点,以便在你的时间到来之前你不能解锁它们。
我只有一天,所以我期待看到我的生产力如何比较每天和每周。因为这是我第一天用它,所以我非常努力,因为我自我意识到我在做什么,但我很好奇,一旦我不再注意它,它会看到它的平均值是什么样的。我知道我通常会浪费很多时间与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)
这不是编程问题。这是一门学科问题。我的建议: