13

我正在尝试从 C# 访问应用程序历史记录。我想提供与任务管理器中相同的信息,但我找不到 api/example。当然,我实现了一个桌面应用程序。

指定问题:我对 CPU/RAM 不感兴趣。我唯一想得到的是时间。

更新 要准确显示我在说什么看这个屏幕: 截屏

4

4 回答 4

10

没有支持的方式来获取此信息。对不起。

于 2013-04-30T22:25:22.983 回答
7

问题的描述缺少您所谈论的 Metro Apps 的详细信息。该解决方案相当于Process.TotalProcessorTimeMetro Apps。

不幸的是,您无法获得该信息,因为正如您所说,应用程序正在另一个进程 (WWAHost.exe) 中运行。Metro 的设计有点像电话——你不能以同样的方式直接操纵系统。Windows 运行时中没有直接的“进程”(参见此处),这反过来意味着 Process 类对移植没有意义......

于 2013-04-30T19:52:03.620 回答
6

我假设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 所花费的时间量。该值是 和 之UserProcessorTimePrivilegedProcessorTime

于 2013-04-30T11:22:40.713 回答
4

我对此进行了一些研究,因为我发现 Metro 应用程序如何集成到现有流程结构中很有趣。

正如其他人在这里指出的那样,不可能以漂亮的受支持的 API 方式获取您想要的信息。但是,每个应用程序都是作为不同的进程启动的,对于进程,有已知的方法来获取运行时间、cpu 时间等。

如果您找到与您的 Windows 8 应用程序对应的进程,您将能够获得所需的信息。

有些应用真的很容易被发现。它们只是一个可执行文件,就像任何其他具有适当进程名称和描述的桌面应用程序一样。例如在这张图片中的“地图”、“Windows 阅读器”和“微软相机应用程序”:

在此处输入图像描述

其他一些应用程序更难发现。它们托管在由wwahost.exe执行程序启动的进程中。我只能通过查看模块列表来发现应用程序名称。这是Bing应用程序:

在此处输入图像描述

要枚举进程中的模块和映射文件,您可以使用 WinAPIs VirtualQueryExGetMappedFileName

然后,您要查找位于%programfiles%\WindowsApps. 这是 Windows 为其应用程序保存所有应用程序文件的文件夹。

每个应用程序都有一个.pri文件。此文件包含应用程序的二进制元数据。您可以使用它从托管它的进程中查找应用程序的名称。在与 .pri 文件相同的文件夹AppxManifest.xml中,您可以在其中找到有关该应用程序的各种附加信息。

我将尝试总结一下我的写作:

  • 使用 WinAPI 枚举进程并获取您需要的所有信息(运行时间、cpu 时间等)。
  • 枚举每个进程的映射文件并查找ressources.pri. 此文件所在的目录中包含应用程序名称。
  • 作为奖励阅读AppxManifest.xml文件以获取有关应用程序的其他信息。您可能需要管理员权限或其他权限才能读取此文件。
于 2013-05-01T21:04:03.490 回答