Know when the computer was turned on / off / stopped

I wanted to know when the computer was turned on, turned off or was interrupted. If I turned on my computer, from today's date, then I want to know the time and date that was turned on. On shutdown the same thing, if I turned off the computer "normally", from today's date, then capture the date and time. If it was interrupted or forced for example, disconnected outside the outlet or lacked power, then capture all this data.

Learned that the Reference: System.Diagnostics.Eventing.Reader contains a set of Classes to get the system event logs, but I don't know how to use.

After much research, I ended up finding the code that generates the system startup and Shutdown Event below.

if (EventLog.Exists("System"))
{
    var log = new EventLog("System", Environment.MachineName, "EventLog");

    var entries = new EventLogEntry[log.Entries.Count];
    log.Entries.CopyTo(entries, 0);

    var startupTimes = entries.Where(x => x.InstanceId == 2147489653).Select(x => x.TimeGenerated);
    var shutdownTimes = entries.Where(x => x.InstanceId == 2147489654).Select(x => x.TimeGenerated);
}

When you pull the time and the date that is in the two variables above, the following result appears:

insert the description of the image here

The time and date are practically wrong. I'm in 2018 and on the date of the two variables I am in 0001. If the date is wrong then it means that the time is too. And also, the two variables are with the same value.

Author: sYsTeM, 2018-07-24

3 answers

The problem mentioned in the question regarding the date presented, is because you were receiving a list and were not querying the value referring to an element of it, only the default of its structure.

I would use a Helper to facilitate the mapping and query of the events you intend, below follows a basic model (using your own code) and an example implementation. This way you will have total freedom to work with the EventLogEntry the way it is more useful.

See Eventoshelper

public static class ConsultaEventosHelper
{
    private const long inicializacao = 2147489653;
    private const long desligamento = 2147484722;
    private const long reinicializacao = 2147489654;

    public static List<EventLogEntry> Inicializacao { get { return ConsultaOcorrencias(inicializacao); } }
    public static List<EventLogEntry> Desligamento { get { return ConsultaOcorrencias(desligamento); } }
    public static List<EventLogEntry> Reinicializacao { get { return ConsultaOcorrencias(reinicializacao); } }

    public static List<EventLogEntry> ConsultaOcorrencias(long instanceId)
    {
        List<EventLogEntry> resultado = new List<EventLogEntry>();

        if (EventLog.Exists("System"))
        {
            using (var log = new EventLog("System", Environment.MachineName, "EventLog"))
            {
                var entries = new EventLogEntry[log.Entries.Count];
                log.Entries.CopyTo(entries, 0);
                resultado = entries.Where(x => x.InstanceId == instanceId).ToList();
            }
        }

        return resultado;
    }
}

Main

static void Main(string[] args)
{


    var ultimaInicializacao = ConsultaEventosHelper.Inicializacao.LastOrDefault();
    var ultimoDesligamento = ConsultaEventosHelper.Desligamento.LastOrDefault(); 
    var ultimaReinicializacao = ConsultaEventosHelper.Reinicializacao.LastOrDefault(); 

    Console.WriteLine("Última Incializacao: {0} - {1}", ultimaInicializacao.TimeGenerated, ultimaInicializacao.Message);
    Console.WriteLine("Última Reinicializacao: {0} - {1}", ultimaReinicializacao.TimeGenerated, ultimaReinicializacao.Message);
    Console.WriteLine("Último Desligamento: {0} - {1}", ultimoDesligamento.TimeGenerated, ultimoDesligamento.Message);


    Console.ReadKey();
}
 3
Author: Leandro Angelo, 2018-07-24 14:22:48

Using a different approach to get the TimeGenerated .

Note: there is usually a delay between the time an event is generated and the time it is logged. It is more important to know when the event was generated, unless you want to see if there is a significant delay in logging. This can happen if your log files are on a different server and you have a bottleneck. Source: https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogentry.timegenerated(v=vs. 110).aspx

 static void Main(string[] args)
        {
            EventLog ev = new EventLog("System", Environment.MachineName);

            if (ev.Entries.Count <= 0)
                Console.WriteLine("Nenhum log de eventos no log :" + "System");

            for (int i = ev.Entries.Count - 1; i >= 0; i--)
            {
                EventLogEntry CurrentEntry = ev.Entries[i];

                DateTime dt = DateTime.Now;
                TimeSpan ts = dt.Subtract( CurrentEntry.TimeGenerated);
                int hours = (ts.Days * 24) + ts.Hours;

                if (CurrentEntry.Source.ToUpper() == "USER32")
                {
                    Console.WriteLine("Tempo gerado:" + CurrentEntry.TimeGenerated);
                    Console.WriteLine("Horas atrás:" + hours);
                    Console.WriteLine("Event Id : " + CurrentEntry.InstanceId);
                    Console.WriteLine("Entry Type : " + CurrentEntry.EntryType.ToString());
                    Console.WriteLine("Mensagem :  " + CurrentEntry.Message + "\n");
                }
            }
            ev.Close();
            Console.ReadLine();
        }

Code source here.

 2
Author: Netinho Santos, 2018-07-24 14:04:28

Can control at least logoff and shutdown as follows:

using Microsoft.Win32;

namespace MyApp
{
    public MyClass()
    {
        SystemEvents.SessionEnding += SystemEvents_SessionEnding;
    }

    private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
    {
        if (e.Reason == SessionEndReasons.Logoff)
        {
            // colocar aqui o código para logoff
        }
        else
        {
            // colocar aqui o código para shutdown
        }
    }
}
 0
Author: João Martins, 2018-07-24 13:18:47