How to know when was Windows started or shutdown?

According to this article you can use WMI to get the last boot date/time.

// define a select query
SelectQuery query =
    new SelectQuery(@"SELECT LastBootUpTime FROM Win32_OperatingSystem
       WHERE Primary='true'");

// create a new management object searcher and pass it
// the select query
ManagementObjectSearcher searcher =
    new ManagementObjectSearcher(query);

// get the datetime value and set the local boot
// time variable to contain that value
foreach(ManagementObject mo in searcher.Get())
{
    dtBootTime =
        ManagementDateTimeConverter.ToDateTime(
            mo.Properties["LastBootUpTime"].Value.ToString());

    // display the start time and date
    txtDate.Text = dtBootTime.ToLongDateString();
    txtTime.Text = dtBootTime.ToLongTimeString();
}

System.Environment.TickCount has a 24.8 days limitation.
This is because TickCount is a millisecond value contained in a signed 32 bits value.

Windows API exposes these two functions:
GetTickCount - returns a 32 bits value - available from Windows 2000
GetTickCount64 - returns a 64 bits value - available from Vista/Windows Server 2008

You can use GetTickCount64 this way:

using System.Runtime.InteropServices;  

[DllImport("Kernel32.dll")]  
static extern long GetTickCount64();  

DateTime osStartTime = DateTime.Now - new TimeSpan(10000 * GetTickCount64());

You can use the classes in System.Diagnostics.Eventing.Reader to access the system Event Logs.


As Reed pointed out you could access the Event Logs and see when they were created. AFAIK there are no specific event entries for system startup/shutdown, but you could look for services that are usually started/stopped with Windows. Though using this approach means it won't be 100% accurate, say if it crashes or it's manually started/stopped/restarted. One event I consider is the most accurate is EventLog service start/stop event.

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

Edit

Turns out there was a shutdown event. You can replace the Linq to get it:

var shutdownEvents = entries.Where(x => x.InstanceId == 2147484722);

Tags:

Windows

C#