2009-10-27 10 views
7

¿Hay alguna manera de averiguar cuándo se cerró por última vez el sistema?Obtenga la fecha y hora del último evento de cierre de Windows con .NET

Sé que hay una manera de averiguarlo último tiempo de arranque utilizando la propiedadLastBootUpTime en Win32_OperatingSystem espacio de nombres WMI utilizando .

¿Hay algo similar para saber la hora del último apagado?

Gracias.

+3

También debes tener en cuenta si usted se preocupa cuando una máquina tiene su poder tiró - que está no va a tener un evento para eso. – serialhobbyist

Respuesta

8

(aquí todo es 100% cortesía de JDunkerley's earlier answer)

La solución es más arriba, pero el enfoque de pasar de una matriz byte a DateTime se puede lograr con menos declaraciones usando el BitConverter. Las siguientes seis líneas de código hacen lo mismo y dan elcorrectodel registro:

public static DateTime GetLastSystemShutdown() 
{ 
    string sKey = @"System\CurrentControlSet\Control\Windows"; 
    Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey); 

    string sValueName = "ShutdownTime"; 
    byte[] val = (byte[]) key.GetValue(sValueName); 
    long valueAsLong = BitConverter.ToInt64(val, 0); 
    return DateTime.FromFileTime(valueAsLong); 
} 
+0

Hmm, gracias por aceptar, pero la solución provista aquí está totalmente basada en la respuesta de JDunkerley, él debería recibir todo el crédito, básicamente ;-) – Abel

+0

Parece que esto el valor no se actualiza cuando la computadora falla :( – Pavenhimself

+1

@Pavenhimself: si la computadora se cuelga, se crea un evento en el registro de eventos _después_ del siguiente inicio (el BSOD en sí evita obviamente que se escriba el tiempo de apagado actual en el registro, o cualquier otra cosa) para el caso, lo único que el sistema hace en BSOD es crear un archivo de volcado). Puede verificar EventID 6008, fuente EventLog. Para encontrar la hora actual, verifique la marca de tiempo en el Archivo de volcado BSOD. – Abel

8

Suponiendo que Windows se apaga sin problemas. Lo almacena en el registro:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\ShutdownTime 

Se almacena como una matriz de bytes, pero es un FILETIME.

Si bien puede haber una mejor manera, he utilizado este antes y creo que funciona:

public static DateTime GetLastSystemShutdown() 
    { 
     string sKey = @"System\CurrentControlSet\Control\Windows"; 
     Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey); 

     string sValueName = "ShutdownTime"; 
     object val = key.GetValue(sValueName); 

     DateTime output = DateTime.MinValue; 
     if (val is byte[] && ((byte[])val).Length == 8) 
     { 
      byte[] bytes = (byte[])val; 

      System.Runtime.InteropServices.ComTypes.FILETIME ft = new System.Runtime.InteropServices.ComTypes.FILETIME(); 
      int valLow = bytes[0] + 256 * (bytes[1] + 256 * (bytes[2] + 256 * bytes[3])); 
      int valTwo = bytes[4] + 256 * (bytes[5] + 256 * (bytes[6] + 256 * bytes[7])); 
      ft.dwLowDateTime = valLow; 
      ft.dwHighDateTime = valTwo; 

      DateTime UTC = DateTime.FromFileTimeUtc((((long) ft.dwHighDateTime) << 32) + ft.dwLowDateTime); 
      TimeZoneInfo lcl = TimeZoneInfo.Local; 
      TimeZoneInfo utc = TimeZoneInfo.Utc; 
      output = TimeZoneInfo.ConvertTime(UTC, utc, lcl); 
     } 
     return output; 
    } 
+0

enfoque +1 bien, eliminé mi publicación, ya que esto es mucho más preciso, parece – Abel

+0

lo siento, no pude resistir, parece que hay una manera un poco más fácil de convertir una matriz de bytes en un "DateTime", espero que no T mente, pero no podría haberlo hecho sin tu respuesta :) – Abel

4

La última vez que reinicio se puede encontrar utilizando este pedazo de código

static void Main(string[] args) 
    {   
     TimeSpan t = TimeSpan.FromMilliseconds(System.Environment.TickCount); 
     Console.WriteLine(DateTime.Now.Subtract(t));   
    } 
Cuestiones relacionadas