Retrieve system uptime using C#

Viewed 48896

Is there a simple way to get a system's uptime using C#?

10 Answers
public TimeSpan UpTime {
    get {
        using (var uptime = new PerformanceCounter("System", "System Up Time")) {
            uptime.NextValue();       //Call this an extra time before reading its value
            return TimeSpan.FromSeconds(uptime.NextValue());
        }
    }
}

System.Environment.TickCount gets the number of milliseconds since the system was restarted.

Beware though that it is an Int32 and will overflow after 24.9 days and will become negative. See the remarks on the MDSN docs.

If you are using a later .NET version (Core 3.0/.NET 5.0 or above), then the Environment class now has a TickCount64 property.

This doesn't suffer from the wrap-around issues of the TickCount property, nor do you have to resort to P/Invoke to get the value.

long tickCountMs = Environment.TickCount64;
var uptime = TimeSpan.FromMilliseconds(tickCountMs);

Simple, no but it can be done:

    static DateTime getLastBootTime(ManagementObject mObject)
    {
        PropertyData pd = mObject.Properties["LastBootUpTime"];
        string name = pd.Name.ToString();
        DateTime lastBoot = parseCmiDateTime(pd.Value.ToString());
        return lastBoot;
    }

    static ManagementObject getServerOSObject(string serverName)
    {
        ManagementObjectSearcher mSearcher = new ManagementObjectSearcher("Select * From Win32_OperatingSystem");
        mSearcher.Scope = new ManagementScope(String.Format(@"\\{0}\root\cimv2", serverName));
        ManagementObjectCollection mObjects = mSearcher.Get();
        if (mObjects.Count != 1) throw new Exception(String.Format("Expected 1 object, returned {0}.", mObjects.Count));
        foreach (ManagementObject m in mObjects)
        {
            //No indexing on collection
            return m;
        }
        throw new Exception("Something went wrong!");
    }

The (one and only) correct answer so far:

Using the 32-bit timer is incredibly dangerous, and prone to error for all but limited use.

I'm not sure when the NativeMethods class stuff was added to .net, but it was. You definitely want to avoid P/Invoke overhead. Do this:

using System;
using System.Runtime.InteropServices;

namespace Mu
{

    // prevents PInvoke (not in NativeMethods class) or Stack walk (NativeMethods class) performance penalties.
    internal static partial class SafeNativeMethods
    {
        [DllImport("kernel32")]
        internal extern static UInt64 GetTickCount64();

    }
    public static class MuTime
    {
        public static UInt64 UpTimeMillis {  get { return SafeNativeMethods.GetTickCount64();  } }
    }
}

/*
Dual License (use either, not both). To avoid CC-BY-SA, access a copy of this 
code at (https://pastebin.com/6EKTWsSf) to use under BSD 0-clause license,


Copyright (c) 2020 Robin Davies 
CC-BY-SA 3.0 (due to StackExchange terms of use). Not my fault, blame StackExchange. Fix this 
please, StackExchange!


BSD 0-Clause
Copyright 2020 Robin Davies.

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, 
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 
THIS SOFTWARE.
  */
Related