我想开发一个应用程序(它可以随时在后台运行)来跟踪应用程序(msword,excel,powerpoint,* .exe等)的使用情况。如何跟踪应用程序使用情况?
我可以处理将数据发布到数据库,但并不知道从何处开始监视正在运行的应用程序(何时启动,何时停止)。任何人有任何线索?
我想开发一个应用程序(它可以随时在后台运行)来跟踪应用程序(msword,excel,powerpoint,* .exe等)的使用情况。如何跟踪应用程序使用情况?
我可以处理将数据发布到数据库,但并不知道从何处开始监视正在运行的应用程序(何时启动,何时停止)。任何人有任何线索?
您可以使用System.Diagnostics.Process.GetProcesses()
定期轮询正在运行的进程的列表。
以下代码输出关于启动和退出进程的信息。退出系统进程将无法识别。
class Program
{
struct ProcessStartTimePair
{
public Process Process { get; set; }
public DateTime StartTime { get; set; }
public DateTime ExitTime
{
get
{
return DateTime.Now; // approximate value
}
}
public ProcessStartTimePair(Process p) : this()
{
Process = p;
try
{
StartTime = p.StartTime;
}
catch (System.ComponentModel.Win32Exception)
{
StartTime = DateTime.Now; // approximate value
}
}
}
static void Main(string[] args)
{
List<ProcessStartTimePair> knownProcesses = new List<ProcessStartTimePair>();
while (true)
{
foreach (Process p in Process.GetProcesses())
{
if (!knownProcesses.Select(x => x.Process.Id).Contains(p.Id))
{
knownProcesses.Add(new ProcessStartTimePair(p));
Console.WriteLine("Detected new process: " + p.ProcessName);
}
}
for (int i = 0; i < knownProcesses.Count; i++)
{
ProcessStartTimePair pair = knownProcesses[i];
try
{
if (pair.Process.HasExited)
{
Console.WriteLine(pair.Process.ProcessName + " has exited (alive from {0} to {1}).", pair.StartTime.ToString(), pair.ExitTime.ToString());
knownProcesses.Remove(pair);
i--; // List was modified, 1 item less
// TODO: Store in the info in the database
}
}
catch (System.ComponentModel.Win32Exception)
{
// Would have to check whether the process still exists in Process.GetProcesses().
// The process probably is a system process.
}
}
Console.WriteLine();
System.Threading.Thread.Sleep(1000);
}
}
}
您可能简单地忽略不允许您阅读HasExited属性的系统进程。
编辑
下面是一个.NET 2.0的版本:
static void Main(string[] args)
{
List<ProcessStartTimePair> knownProcesses = new List<ProcessStartTimePair>();
while (true)
{
foreach (Process p in Process.GetProcesses())
{
if (!ProcessIsKnown(knownProcesses, p.Id))
{
knownProcesses.Add(new ProcessStartTimePair(p));
Console.WriteLine("Detected new process: " + p.ProcessName);
}
}
for (int i = 0; i < knownProcesses.Count; i++)
[...]
}
}
static bool ProcessIsKnown(List<ProcessStartTimePair> knownProcesses, int ID)
{
foreach (ProcessStartTimePair pstp in knownProcesses)
{
if (pstp.Process.Id == ID)
{
return true;
}
}
return false;
}
注意,代码可以改善,只能说明这个概念。
您可以定期轮询所有顶级窗口并记录窗口标题文本;并在此基础上就运行哪个程序做出一些结论。
或者你可以通过进程名称或组合来完成。
有关枚举窗口,请参见http://msdn.microsoft.com/en-us/library/ms633497(VS.85).aspx和here is how to use it in managed code。 若要枚举进程,请使用Process.GetProcesses方法或参见http://www.codeproject.com/KB/threads/enumprocess.aspx
轮询是容易的,但你真的应该挂钩到win32的事件,而是接受当这些事情发生的通知。
我有一个类似的边项目来创建一个“任务栏”类型的应用程序。我的目标是在窗口移动/创建/关闭时通知应用程序,以便我可以使用此信息来显示/更新UI。
bb4win程序有这个“层”它可以捕捉不同种类的系统通知,并使用它来创建一个替代桌面外壳。源代码是可用的,并用c编码。
这是我以前用Win32 Hooks开始的链接。
它可以使用通知WMI当流程启动/退出
A full working example is in a blog post on ASP.NET。
它的基本功能(从博客帖子后人复制):
创建一个类,从ManagementEventWatcher
在构造函数中继承,设置:
this.Query.QueryLanguage = "WQL";
this.Query.QueryString = @"SELECT * FROM
__InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'";
this.EventArrived += watcher_EventArrived; // Delegate for EventArrivedEventHandler
private void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
string eventType = e.NewEvent.ClassPath.ClassName;
Win32_Process proc = new
Win32_Process(e.NewEvent["TargetInstance"] as ManagementBaseObject);
switch (eventType)
{
case "__InstanceCreationEvent":
Console.WriteLine("Process Created");
break;
case "__InstanceDeletionEvent":
Console.WriteLine("Process Deleted (Ended)");
break;
case "__InstanceModificationEvent":
Console.WriteLine("Process Modified (possibly still running)");
break;
}
}
当进程dis出现?你需要每分钟轮询一分钟才能获得1分钟的分辨率吗? – 2009-06-23 20:39:39