C#中的Windows 8 taskmanager应用程序历史记录#

问题描述:

我试图从C#访问应用程序历史记录。我想在任务管理器中显示相同的信息,但我找不到API /示例。当然,我实现了一个桌面应用程序。C#中的Windows 8 taskmanager应用程序历史记录#

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

UPDATE 为准确显示什么我谈论一下这个屏幕: Screen shot

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

正如其他人在这里指出的,它是不可能在一个美丽的受支持的API方式获得您想要的信息。 但是,每个应用程序都作为一个不同的进程启动,并为进程有已知的方式来获得运行时间,cpu时间等。

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

某些应用程序很容易找到。它们只是一个像任何其他桌面应用程序一样的可执行文件,具有适当的进程名称和说明 例如在这张照片“地图”,“视窗读者”和“微软摄像头应用程序”:

enter image description here

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

enter image description here

枚举模块,并从流程映射文件可以使用WinAPIs VirtualQueryExGetMappedFileName

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

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

我会试着总结一下我写了一下:

  • 与WinAPI的枚举进程,并得到你所需要的所有相关信息(运行时间,CPU时间等)。
  • 枚举每个进程的映射文件并查找ressources.pri。该文件所在的目录中包含应用程序名称。
  • 作为奖励阅读AppxManifest.xml文件的应用程序的其他信息。您可能需要管理员权限或其他权限才能读取此文件。
+0

好的答案!这将是他可以得到的最好的,但仍然不会让他得到每个模块的CPU时间,这是他正在寻找的信息。这只提供了模块或“进程”的列表 – 2013-05-02 08:15:06

+0

有了这些信息,我可以创建我自己的统计信息,这可能是最好的,我可以得到:) – 2013-05-02 10:32:08

+0

我假设Windows 8任务管理器也“只”从CPU时间应用程序的主机进程。由于每个应用程序都会产生一个新的过程,我也不明白为什么这些值会有所不同。 – typ1232 2013-05-02 10:32:10

我通过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 LIK它:

Process Class

编辑:

,我可以从您的评论看,你有兴趣在CPU已经花了运行的特定进程的时间。同样的System.Diagnostics.Process类也包含该信息。这可以使用Process.PrivilegedProcessorTime属性找到。此属性的MSDN说明是:

TimeSpan指示进程在操作系统内核中运行代码所花费的时间量。

更多信息Here

编辑2:

以下2个属性还可以给你你需要的可能就是:

Process.UserProcessorTimeHere

一个TimeSpan指示相关进程花费的时间代码在进程的应用程序部分内(不在操作系统内核中)。

Process.TotalProcessorTimeHere

一个TimeSpan指示相关联的处理已经使用了利用CPU的时间量。该值是UserProcessorTimePrivilegedProcessorTime的总和。

+0

你误解了我的问题。我想在Windows 8中显示与任务管理器中相同的信息。我正在讨论此功能:http://cdn3.pcadvisor.co.uk/cmsdata/features/3422276/Win8-Task-Manager-2.jpg而且,所有Windows 8中的地铁应用程序托管在名为wwahost的过程中 – 2013-04-30 17:17:27

+0

尽我所能了解您的一行问题结果以投票方式投票? Humm ..有趣的 – 2013-04-30 17:54:20

+0

就在你提供的图片中:你在哪里看到一个“时间”在哪里? – 2013-04-30 17:55:02

这些问题的描述缺少您谈论Metro应用程序的细节。该解决方案将相当于Process.TotalProcessorTime,但对于Metro应用程序。

不幸的是,您无法获取该信息,因为正如您所述,这些应用程序正在另一个进程(WWAHost.exe)中运行。 Metro的设计更像电话 - 您不能以相同的方式直接操纵系统。在Windows运行时中没有直接“进程”(请参见here),这反过来意味着进程类对端口没有意义...

+0

对于这个答案我应该给你-1。如果任务管理器如何做到这一点是不可能的。你说得对,WinRT是不可能的,但它必须可以从WinApi中获得。我的问题是由Windows 8标记的,我写了关于应用程序历史和任务管理器的内容。你是对的图像链接丢失,但仍然你的答案是不正确的 – 2013-04-30 20:25:44

+1

我尽了最大的帮助。如果某件事情不可能发生并不一定意味着答案是错误的。我收录了参考资料,并花费了相当多的时间试图找出解决方案,这些都是我想出的答案。抱歉没有提供符合您的期望的解决方案。 – 2013-04-30 20:41:33

+0

但是这可能是因为任务管理器显示此信息。我可以理解微软隐藏这个API,但他们使用它 – 2013-04-30 22:23:57

没有支持的方式获取此信息。抱歉。

+0

不支持? – 2013-05-01 05:24:12

+10

没有。我不会让你通过做不受支持的事情来搞砸你的客户。 – 2013-05-01 12:40:11