Know when the computer was turned On / Off / Stopped

3

I wanted to know when the computer was turned on, turned off, or stopped. If I turned on my computer, from today's date, then I want to know the time and date it was connected. On shutting down the same thing, if I shut down the computer "normally" from today's date, then capture the date and time. If it was interrupted or forced for example, disconnected out of the socket or lacked power, then capture all this data.

I learned that the reference: System.Diagnostics.Eventing.Reader Contains a set of Classes to get system event logs , but I do not know how to use it.

After much research, I ended up finding the code that generates the start and shutdown event of the system 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 pulling the schedule and the date that is in the two variables above, the following result appears:

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

    
asked by anonymous 24.07.2018 / 13:57

3 answers

3

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

I would use a Helper to make it easier to map and query the events you want, below is a basic template (using your own code) and an implementation example. This way you will have complete freedom to work with EventLogEntry in the most useful way.

QueryEventsHelper

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();
}
    
24.07.2018 / 16:12
2

Using a different approach to get the TimeGenerated .

  

Note: Generally, there is a delay between the time an event is generated and the time at which 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 the log. This can happen if your log files are on a different server and you have a bottleneck. Source: link

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

Source code here.

    
24.07.2018 / 15:37
0

You 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
        }
    }
}
    
24.07.2018 / 15:18