13

I am trying to access application history from C#. I would like to present same information as in task manager, but I cannot find api/example. Of course I implement a desktop application.

To specify problem: I am not interested on CPU/RAM. The only thing I would like to get is Time.

UPDATE To exactly show what I am talking about look at this screen: Screen shot

Daedalus
  • 7,586
  • 5
  • 36
  • 61
Piotr Stapp
  • 19,392
  • 11
  • 68
  • 116

4 Answers4

10

There is no supported way to get this information. Sorry.

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
7

The description of the questions lacks details that you are talking about Metro Apps. The solution would be an equivalent of Process.TotalProcessorTime but for Metro Apps.

Unfortunately, you cannot get that information because as you stated the applications are running within another process (WWAHost.exe). The design of Metro is a bit more like the phone - you can't directly manipulate the system in the same way. There isn't a directly "Process" in the Windows Runtime (see here), which in turn means the Process class wouldn't make sense to port...

Moslem Ben Dhaou
  • 6,897
  • 8
  • 62
  • 93
  • For this answer I should give you -1. If it is impossibly how the task manager do this. You are right that it's impossible from WinRT but it must be possible from WinApi. My question was tagged by windows 8 and I wrote about application history and task manager. You are right that link to image was missing,but still both your answers are incorrect – Piotr Stapp Apr 30 '13 at 20:25
  • 1
    I did my best to help. If something is not possible that does not necessarily mean the answer is wrong. I included references and spent quite a lot of time trying to figure out a solution and these are the answers I came up with. Sorry for not providing a solution up to your expectations. – Moslem Ben Dhaou Apr 30 '13 at 20:41
  • But it is possible beccause task manager show this info. I can understand that Microsoft hides this API but they use it – Piotr Stapp Apr 30 '13 at 22:23
  • 3
    @Garath "I can understand that Microsoft hides this API but they use it". Task Manager is much more closely integrated with the OS than your app is allowed to be. It is also a desktop application, probably written in C or C++ with direct hooks into the OS, not a Windows 8 app written in much higher-level C#. – Moshe Katz May 01 '13 at 00:22
  • If task manager can invoke some system function my c# code can invoke it also using pinvoke. C# can directly call winwin32api. Anyway access from C will be good enough for me – Piotr Stapp May 01 '13 at 05:29
  • @Garath: what if the function is included within the Task manager and not a system function? – Moslem Ben Dhaou May 01 '13 at 07:44
  • Still it has to be stored on disk because it does not reset after shutdown – Piotr Stapp May 01 '13 at 11:33
  • Please have a look at this question it might help http://stackoverflow.com/questions/12338953/is-there-any-way-for-a-winrt-app-to-measure-its-own-cpu-usage – Moslem Ben Dhaou May 01 '13 at 13:18
  • These are the system APIs supported for developing Windows Store apps. (Win32 and COM). I tried to find an adequate function but I am still not sure exactly. Please have a look http://msdn.microsoft.com/en-us/library/windows/apps/br205762.aspx – Moslem Ben Dhaou May 01 '13 at 13:20
  • The main problem is that it won't be Windows Store app. It has to be Win32Api application. WinRT cannot access to other apps, because it is sandboxed (but I am sure that you know about it) – Piotr Stapp May 02 '13 at 10:24
6

I assume by The only thing I would like to get is Time. you mean the start and end time of each process

The best way will be that you will have to build that history your self. If you need the history only when your application is running then you just implement the code bellow otherwise if you wish to build the history for a certain period even when your application is down then try to create a Windows service that does the job for you. Following are the steps you need to do assuming you know how to create a windows service project, compile and install it:

Getting running processes info :

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);
    }
}

Getting new started processes

You need to create a new Timer object and run it every second checking for new created processes. I copied the code above and extended it :

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);
            }
        }
    }
}

Finally :

You just then need to play with the System.Diagnostics.Process class. That should be your best way for getting all information you need about windows processes. It will grant you access to a wide range of properties and methods. Here is the official MSDN lik for it:

Process Class

EDIT :

As I can see from your comment, you are interested in the time the CPU have spent running a specific process. The same System.Diagnostics.Process class contains that info as well. That can be found using the Process.PrivilegedProcessorTime property. The MSDN description for this property is :

A TimeSpan that indicates the amount of time that the process has spent running code inside the operating system core.

More information Here

EDIT 2:

The following 2 Properties could also give you probably what you need:

Process.UserProcessorTime : Here

A TimeSpan that indicates the amount of time that the associated process has spent running code inside the application portion of the process (not inside the operating system core).

Process.TotalProcessorTime : Here

A TimeSpan that indicates the amount of time that the associated process has spent utilizing the CPU. This value is the sum of the UserProcessorTime and the PrivilegedProcessorTime.

Moslem Ben Dhaou
  • 6,897
  • 8
  • 62
  • 93
  • You misunderstood my question. I want to present same information as in task manager in windows 8. I was talking about this feature: http://cdn3.pcadvisor.co.uk/cmsdata/features/3422276/Win8-Task-Manager-2.jpg Moreover all Metro apps in Windows 8 are hosted in on process called wwahost – Piotr Stapp Apr 30 '13 at 17:17
  • Doing my best to understand your one line question results in a down vote? Humm.. interesting – Moslem Ben Dhaou Apr 30 '13 at 17:54
  • just in the picture you provided: where do you see a `Time` anywhere? – Moslem Ben Dhaou Apr 30 '13 at 17:55
  • Wrong image attached: http://cdn3.pcadvisor.co.uk/cmsdata/features/3422276/Win8-Task-Manager-4.jpg. – Piotr Stapp Apr 30 '13 at 18:32
  • The downvote was accident sorry. I cannot change it until you edit you answer – Piotr Stapp Apr 30 '13 at 18:34
  • I remove my down vote. Still your answer is completely not what I am looking. – Piotr Stapp Apr 30 '13 at 18:50
  • Can you provide more details? What does the time represent? – Moslem Ben Dhaou Apr 30 '13 at 18:54
  • On this screen there is a column "CPU time", if you have windows 8 you can check it yourself. All apps listed in this view are WinRT apps. All of them are hosted in on process wwahost, so I cannot simply get process – Piotr Stapp Apr 30 '13 at 18:58
4

I've done some research on this, because I found it to be interesting how the metro apps integrate into the existing process structure.

As other people have pointed out here, it is not possible in a beautiful supported API way to get the info you want. However, every app is launched as a different process and for processes there are known ways to get run time, cpu time etc.

If you find the correspondig process to your windows 8 app, you will be able to get the info you need.

Some apps are really easy to spot. They are just a executable like any other desktop application with a proper processname and description. For example in this picture "Map", "Windows Reader" and "Microsoft Camera Application":

enter image description here

Some other apps are a bit harder to spot. They are hosted in a process that is launched by the wwahost.exe executabe. I could only spot the app name by looking at the module list. This is the Bing app:

enter image description here

To enumerate the modules and mapped files from a process you can use the WinAPIs VirtualQueryEx and GetMappedFileName.

Then you want to look for files that are located at %programfiles%\WindowsApps. This is the folder where windows saves all the application files for it's apps.

Every app has a .pri file. This file contains binary metadata of the application. You could use it to find the name of the app from the process that is hosting it. In the same folder with the .pri file there is a AppxManifest.xml in which you could find all kinds of additional information about the app.

I will try to summarize my writing a bit:

  • enumerate processes with WinAPI and get all infos you need (run time, cpu time, etc).
  • enumerate mapped files of each process and look for ressources.pri. The directory where this file is located has the app name in it.
  • as bonus read the AppxManifest.xml file for additional info on the app. You might need Administrator privilege or additional privileges to read this file.
yoozer8
  • 7,361
  • 7
  • 58
  • 93
typ1232
  • 5,535
  • 6
  • 35
  • 51
  • Nice answer! That would be the best he can get but still wont let him get the CPU time for each module which is the information he is looking for. This only provides the list of modules or "Processes" – Moslem Ben Dhaou May 02 '13 at 08:15
  • With this information I can create my own statistic which are probably the best I can get :) – Piotr Stapp May 02 '13 at 10:32
  • I am assuming that the Windows 8 task manager also "only" gets the CPU time from the host process of the app. Since every app spawns a new process I also don't see why the values should differ. – typ1232 May 02 '13 at 10:32