【发布时间】:2013-04-22 18:44:36
【问题描述】:
我正在尝试从 C# 访问应用程序历史记录。我想提供与任务管理器中相同的信息,但我找不到 api/example。当然我实现了一个桌面应用程序。
指定问题:我对 CPU/RAM 不感兴趣。我唯一想得到的就是时间。
更新 要准确显示我正在谈论的内容,请查看此屏幕:
【问题讨论】:
我正在尝试从 C# 访问应用程序历史记录。我想提供与任务管理器中相同的信息,但我找不到 api/example。当然我实现了一个桌面应用程序。
指定问题:我对 CPU/RAM 不感兴趣。我唯一想得到的就是时间。
更新 要准确显示我正在谈论的内容,请查看此屏幕:
【问题讨论】:
不支持获取此信息的方法。对不起。
【讨论】:
问题的描述缺少您所说的 Metro Apps 的详细信息。该解决方案相当于Process.TotalProcessorTime,但适用于 Metro Apps。
不幸的是,您无法获得该信息,因为正如您所说,应用程序正在另一个进程 (WWAHost.exe) 中运行。 Metro 的设计有点像电话——你不能以同样的方式直接操纵系统。 Windows 运行时中没有直接的“进程”(请参阅here),这反过来意味着进程类无法移植......
【讨论】:
我假设The only thing I would like to get is Time. 是指每个进程的开始和结束时间
最好的方法是你必须自己建立这段历史。如果您仅在应用程序运行时才需要历史记录,那么您只需执行下面的代码,否则如果您希望在某个时间段内构建历史记录,即使您的应用程序已关闭,请尝试创建一个为您完成这项工作的 Windows 服务。假设您知道如何创建、编译和安装 Windows 服务项目,以下是您需要执行的步骤:
获取正在运行的进程信息:
using System;
using System.Diagnostics;
public static class ProcessStart
{
Process[] runningProcesses;
var processesStartTimes = new Dictionary<int, Datetime>();
var processesExitTimes = new Dictionary<int, Datetime>();
static ProcessStart()
{
// This will get current running processes
runningProcesses = Process.GetProcesses();
foreach (var p in processes)
{
p.Exited += new EventHandler(ProcessExited);
processesStartTimes.Add(p.Id, p.StartTime);
}
}
private void ProcessExited(object sender, System.EventArgs e)
{
var p = (Process)sender;
processesExitTimes.Add(p.Id, p.ExitTime);
}
}
开始新的流程
您需要创建一个新的Timer 对象并每隔一秒运行一次以检查新创建的进程。我复制了上面的代码并对其进行了扩展:
public static class ProcessStart
{
Process[] runningProcesses;
var processesStartTimes = new Dictionary<int, Datetime>();
var processesExitTimes = new Dictionary<int, Datetime>();
var updateTimer = new Timer(1000);
static ProcessStart()
{
// This will get current running processes
runningProcesses = Process.GetProcesses();
foreach (var p in processes)
{
p.Exited += new EventHandler(ProcessExited);
processesStartTimes.Add(p.Id, p.StartTime);
}
updateTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}
private void ProcessExited(object sender, System.EventArgs e)
{
var p = (Process)sender;
processesExitTimes.Add(p.Id, p.ExitTime);
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
runningProcesses = Process.GetProcesses();
foreach (var p in processes)
{
// This will only add the processes that are not added yet
if (!processesStartTimes.Keys.Contains(p.Id))
{
p.Exited += new EventHandler(ProcessExited);
processesStartTimes.Add(p.Id, p.StartTime);
}
}
}
}
最后:
然后您需要使用System.Diagnostics.Process 类。这应该是获取有关 Windows 进程所需的所有信息的最佳方式。它将授予您访问各种属性和方法的权限。这是官方的 MSDN 赞:
编辑:
从您的评论中可以看出,您对 CPU 运行特定进程所花费的时间感兴趣。同样的System.Diagnostics.Process 类也包含该信息。这可以使用Process.PrivilegedProcessorTime 属性找到。此属性的 MSDN 描述是:
一个 TimeSpan,表示进程在操作系统内核中运行代码所花费的时间。
更多信息Here
编辑 2:
以下 2 个属性也可以满足您的需求:
Process.UserProcessorTime : Here
一个 TimeSpan,指示相关进程在进程的应用程序部分(而不是操作系统核心)内运行代码所花费的时间。
Process.TotalProcessorTime : Here
一个 TimeSpan,指示相关进程使用 CPU 所花费的时间。该值是UserProcessorTime 和PrivilegedProcessorTime 的总和。
【讨论】:
Time?
我对此进行了一些研究,因为我发现 Metro 应用程序如何集成到现有流程结构中很有趣。
正如其他人在这里指出的那样,不可能以漂亮的受支持的 API 方式获取您想要的信息。 但是,每个应用程序都是作为不同的进程启动的,对于进程,有已知的方法来获取运行时间、cpu 时间等。
如果您找到与您的 Windows 8 应用程序对应的进程,您将能够获得所需的信息。
有些应用真的很容易被发现。它们只是一个可执行文件,就像任何其他具有适当进程名称和描述的桌面应用程序一样。 例如这张图片中的“Map”、“Windows Reader”和“Microsoft Camera Application”:
其他一些应用程序更难发现。它们托管在由wwahost.exe 执行程序启动的进程中。我只能通过查看模块列表来发现应用程序名称。
这是Bing 应用程序:
要枚举进程中的模块和映射文件,您可以使用 WinAPI VirtualQueryEx 和 GetMappedFileName。
然后您要查找位于%programfiles%\WindowsApps 的文件。这是 Windows 为其应用程序保存所有应用程序文件的文件夹。
每个应用都有一个.pri 文件。此文件包含应用程序的二进制元数据。您可以使用它从托管它的进程中查找应用程序的名称。在与 .pri 文件相同的文件夹中,有一个 AppxManifest.xml,您可以在其中找到有关该应用程序的各种附加信息。
我会试着总结一下我的写作:
ressources.pri。该文件所在的目录中包含应用名称。AppxManifest.xml 文件以获取有关应用程序的更多信息。您可能需要管理员权限或其他权限才能读取此文件。【讨论】: