Domanda

Vorrei sapere quando è stata l'ultima volta è stato avviato il sistema.

Environment.TickCount funzionerà, ma è rottura dopo 48-49 giorni a causa della limitazione di int.

Questo è il codice che ho usato:

Environment.TickCount & Int32.MaxValue

Qualcuno conosce ritorno tipo lungo in qualche modo?

Sto usando questo per conoscere il tempo di inattività del sistema:

public static int GetIdleTime()
{
    return (Environment.TickCount & Int32.MaxValue)- (int)GetLastInputTime();
}

/// <summary>
/// Get the last input time from the input devices.
/// Exception: 
/// If it cannot get the last input information then it throws an exception with 
/// the appropriate message.
/// </summary>
/// <returns>Last input time in milliseconds.</returns>
public static uint GetLastInputTime()
{
    LastInputInfo lastInPut = new LastInputInfo();
    lastInPut.BlockSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut);
    if (!GetLastInputInfo(ref lastInPut))
    {
        throw new Exception(GetLastError().ToString());
    }

    return lastInPut.Time;
}
È stato utile?

Soluzione

public void BootTime(){    
    SelectQuery query = new SelectQuery("SELECT LastBootUpTime FROM Win32_OperatingSystem WHERE Primary='true'");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

    foreach (ManagementObject mo in searcher.Get())
    {
        DateTime dtBootTime = ManagementDateTimeConverter.ToDateTime(mo.Properties["LastBootUpTime"].Value.ToString());
        Console.WriteLine(dtBootTime.ToString());
    }
}

Altri suggerimenti

siete sulla strada giusta che Environment.TickCount traboccherà dopo circa 25 giorni, perché il valore di ritorno è un intero a 32 bit.

Ma c'è un modo migliore che cercare di confrontare la TickCount se si vuole determinare quando il sistema è stato avviato lo scorso. Quello che stai cercando si chiama sistema di up-tempo . Ci sono un paio di modi diversi che è possibile recuperare questo.

Il modo più semplice è quello di utilizzare la classe PerformanceCounter (nello spazio dei nomi System.Diagnostics), che ti permette di interrogare un particolare contatore di prestazioni del sistema. Provate il seguente codice:

TimeSpan upTime;
using (var pc = new PerformanceCounter("System", "System Up Time"))
{
    pc.NextValue();    //The first call returns 0, so call this twice
    upTime = TimeSpan.FromSeconds(pc.NextValue());
}
Console.WriteLine(upTime.ToString());

In alternativa, è possibile farlo attraverso WMI . Ma sembra che di stian.net risposta è quella coperta.

Si noti, infine, che il nome del contatore delle prestazioni deve essere localizzato se è necessario supportare le versioni internazionali di Windows, in modo che la soluzione corretta deve guardare le stringhe localizzate per "Sistema" e "System Up Time" utilizzando PdhLookupPerfNameByIndex , oppure è necessario assicurarsi che si sta utilizzando il PdhAddEnglishCounter sotto il cofano, che è supportato solo Vista o superiore. Ulteriori su questi qui .

Il codice seguente recupera i millisecondi dall'avviamento del sistema (chiamata API unmanged). Ho misurato i costi di prestazioni per questa operazione interoperabilità, ed è del tutto identica a cronometro () (ma che non recupera il tempo di avvio del sistema in quanto direttamente ovviamente).

using System.Runtime.InteropServices;

...

[DllImport("kernel32.dll") ]
public static extern UInt64 GetTickCount64();

...

var tickCount64 = GetTickCount64();

https: // msdn .microsoft.com / de-dE / library / windows / desktop / ms724411 (v = vs.85) aspx

Se si contano ogni avvolgente, è possibile rendere il proprio 64-bit TickCount, buono per 2 ^ 63 ms (292 milioni di anni) o 2 ^ 64 ms (585 milioni di anni). Se non è necessario il 1ms precisione completa (in realtà solo 10-16ms risoluzione) o un intervallo, è possibile dividere il risultato per 1000 e rappresentare fino al 49,710 giorni (136 anni), con una risoluzione di un secondo, in un UInt32.

GetTickCount64() lo fa per voi, ma è disponibile solo in Vista o versioni successive.

Qui contano le avvolgenti di tempo trascorso, non TickCount.

// C# (untested)
...
// Initialize and start timer:
uint uiT0 = unchecked((uint)Environment.TickCount);  // T0 is NOW.  // ms since boot, 10-16ms res.
uint uiElapsedPrev = 0;
uint uiWrapCount = 0;
...
long x = GetElapsedTime();

public static long GetElapsedTime()
{
    uint uiElapsed = unchecked((uint)Environment.TickCount - uiT0)  // 0 to +49.71 days

    if (uiElapsed < uiElapsedPrev)  // IF uiElapsed decreased,
        uiWrapCount++;  // increment the wrap counter.
    uiElapsedPrev = uiElapsed;  // Save the previous value.

    return ( ((long)uiWrapCount << 32) + (long)uiElapsedPrev );
}

AND con Int32.MaxValue è inutile e un cattivo esempio nella documentazione di .NET. sottrazione incontrollato di interi a 32 bit overflow in modo sicuro. Il segno di Environment.TickCount non conta. maniglie sottrazione tutti i casi che avvolgono. Esempio, avvolgente da uno: uiT0 = Int32.MaxValue; iTickNow = uiT0 + 1 rendimenti Int32.MinValue; infine,. (iTickNow - uiT0) produce 1

tracce uiElapsed tempo trascorso fino a 49,7 giorni prima che si avvolge a zero. Ogni volta che avvolge, iWrapCount viene incrementato. GetElapsedTime () deve essere convocata almeno una volta ogni 49,7 giorni, in modo che non passa inosservato avvolgente.

Credo che sia solo il modo in cui hanno implementato esso.

Si va da 0 a massimo e poi va da un minimo di 0.

https: // msdn .microsoft.com / en-us / library / system.environment.tickcount (v = vs.110) aspx

Ho modificato il codice che si sta utilizzando da http://www.codeproject.com/Articles/13384/Getting-the-user-idle-time-with-C

Perché non solo ottenere il numero assoluto?

    Public Shared Function GetIdle() As UInteger
        Dim lii As New LASTINPUTINFO()
        lii.cbSize = Convert.ToUInt32((Marshal.SizeOf(lii)))
        GetLastInputInfo(lii)

        Dim totalTicks As Long = 0

        If Environment.TickCount > 0 Then
            totalTicks = Convert.ToUInt64(Environment.TickCount)
        Else
            totalTicks = Convert.ToUInt64(Environment.TickCount * -1)
        End If

        Return Math.Abs(totalTicks - lii.dwTime)

    End Function

Io non sono un fan di utilizzare GetTickCount () per timestamp perché può restituire i numeri negativi. Anche se con Abs () può aiutare, ma è scomodo e non è una soluzione ottimale.

E 'meglio usare Cronometro in .Net o QueryPerformanceCounter in C ++ come timestamp.

In un'applicazione C #, ho creare un oggetto cronometro globale, avviarlo. Più tardi nella domanda, io uso le Stopwatch.ElapsedMiliseconds come timestamp.

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace MiscApp
{
    public partial class Form1 : Form
    {
        private Stopwatch globalTimer = new Stopwatch();
        private long myStamp1 = 0;
        public Form1()
        {
            InitializeComponent();
            globalTimer.Start();
        }

        private void SomeFunction()
        {
            if (globalTimer.ElapsedMilliseconds - myStamp1 >= 3000)
            {
                myStamp1 = globalTimer.ElapsedMilliseconds;
                //Do something here...
            }
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top