2009-10-27 3 views
7

Czy istnieje sposób sprawdzenia, kiedy system został ostatnio zamknięty?Uzyskaj datę i godzinę ostatniego zdarzenia zamknięcia systemu przy użyciu .NET

wiem, istnieje sposób, aby dowiedzieć się ostatni czas rozruchu przy użyciu LastBootUpTime nieruchomość w Win32_OperatingSystem nazw używając WMI.

Czy jest coś podobnego do ostatniego czasu zamknięcia?

Dzięki.

+3

Trzeba także rozważyć, czy cię to obchodzi, gdy maszyna ma jego moc wyciągnął - jesteś nie dostaniesz za to wydarzenia. – serialhobbyist

Odpowiedz

8

(tutaj wszystko jest w 100% dzięki uprzejmości JDunkerley's earlier answer)

Rozwiązaniem jest powyżej, ale podejście przechodzenia od tablicy byte do DateTime można uzyskać za pomocą mniejszej liczby instrukcji przy użyciu BitConverter. Poniższe sześć linii kodu robi to samo i podaje prawidłową wartość DateTime z rejestru:

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, dziękuję za akceptację, ale rozwiązanie tutaj dostarczone jest całkowicie oparte na odpowiedzi JDunkerleya, powinien on otrzymać cały kredyt, zasadniczo ;-) – Abel

+0

Wygląda na to wartość nie jest aktualizowana, gdy komputer się zawiesza :( – Pavenhimself

+1

@Pavenhselfself: jeśli komputer się zawiesza, zdarzenie w dzienniku zdarzeń jest tworzone po następnym rozruchu (samo BSOD oczywiście uniemożliwia zapisanie rzeczywistego czasu zamknięcia w rejestrze lub cokolwiek innego o to chodzi, jedyną rzeczą, którą system robi na BSOD, jest utworzenie pliku zrzutu) Można sprawdzić EventID 6008, source EventLog. Aby znaleźć aktualny czas, sprawdź znacznik czasu na Plik zrzutu BSOD. – Abel

8

Zakładając, że system Windows jest płynnie wyłączany. Przechowuje ją w rejestrze:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\ShutdownTime 

to jest przechowywane w postaci tablicy bajtów ale to FILETIME.

Chociaż nie może być lepszy sposób, użyłem tego wcześniej i że to działa:

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

+1 grzywny podejście, usunąłem mój post, ponieważ jest to o wiele bardziej dokładne wydaje się, – Abel

+0

przepraszam, nie mogłem się oprzeć, wydaje się być nieco łatwiejszy sposób na konwersję tablicy bajtów na 'DateTime', mam nadzieję, że nie T mind, ale nie mogłem tego zrobić bez twojej odpowiedzi :) – Abel

4

Ostatnio Restart można znaleźć za pomocą tego fragmentu kodu

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