我正在尝试从 C# 访问应用程序历史记录。我想提供与任务管理器中相同的信息,但我找不到 api/example。当然,我实现了一个桌面应用程序。
指定问题:我对 CPU/RAM 不感兴趣。我唯一想得到的是时间。
更新 要准确显示我在说什么看这个屏幕:
没有支持的方式来获取此信息。对不起。
问题的描述缺少您所谈论的 Metro Apps 的详细信息。该解决方案相当于Process.TotalProcessorTime
Metro Apps。
不幸的是,您无法获得该信息,因为正如您所说,应用程序正在另一个进程 (WWAHost.exe) 中运行。Metro 的设计有点像电话——你不能以同样的方式直接操纵系统。Windows 运行时中没有直接的“进程”(参见此处),这反过来意味着 Process 类对移植没有意义......
我假设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 指示进程在操作系统内核中运行代码所花费的时间。
更多信息在这里
编辑2:
以下 2 个属性也可以为您提供所需的内容:
Process.UserProcessorTime
:这里
TimeSpan 指示关联进程在进程的应用程序部分(而不是操作系统核心)内运行代码所花费的时间量。
Process.TotalProcessorTime
:这里
TimeSpan 指示关联进程使用 CPU 所花费的时间量。该值是 和 之UserProcessorTime
和PrivilegedProcessorTime
。
我对此进行了一些研究,因为我发现 Metro 应用程序如何集成到现有流程结构中很有趣。
正如其他人在这里指出的那样,不可能以漂亮的受支持的 API 方式获取您想要的信息。但是,每个应用程序都是作为不同的进程启动的,对于进程,有已知的方法来获取运行时间、cpu 时间等。
如果您找到与您的 Windows 8 应用程序对应的进程,您将能够获得所需的信息。
有些应用真的很容易被发现。它们只是一个可执行文件,就像任何其他具有适当进程名称和描述的桌面应用程序一样。例如在这张图片中的“地图”、“Windows 阅读器”和“微软相机应用程序”:
其他一些应用程序更难发现。它们托管在由wwahost.exe
执行程序启动的进程中。我只能通过查看模块列表来发现应用程序名称。这是Bing
应用程序:
要枚举进程中的模块和映射文件,您可以使用 WinAPIs VirtualQueryEx和GetMappedFileName。
然后,您要查找位于%programfiles%\WindowsApps
. 这是 Windows 为其应用程序保存所有应用程序文件的文件夹。
每个应用程序都有一个.pri
文件。此文件包含应用程序的二进制元数据。您可以使用它从托管它的进程中查找应用程序的名称。在与 .pri 文件相同的文件夹AppxManifest.xml
中,您可以在其中找到有关该应用程序的各种附加信息。
我将尝试总结一下我的写作:
ressources.pri
. 此文件所在的目录中包含应用程序名称。AppxManifest.xml
文件以获取有关应用程序的其他信息。您可能需要管理员权限或其他权限才能读取此文件。