Antony
Antony

Reputation: 83

How long the PC has been started?

I would like to know how long the PC has been started. That's why I made the following routine:

Public Function LipPCIsOn() As String
  Dim iTempoPC As Integer
  Dim tTempoPC As TimeSpan
  Dim strTempoPC As String
  iTempoPC = System.Environment.TickCount
  tTempoPC = TimeSpan.FromMilliseconds(iTimePC)
  strTempoPC = tTempoPC.Duration.ToString("hh:mm:ss")
  Return strTempoPC
End Function

But I do not understand, the PC despite having been started by 3 minutes it tells me: 7:54:36 Where's the mistake? Thank you all

Upvotes: 1

Views: 323

Answers (2)

Antony
Antony

Reputation: 83

Thank you all. I just wanted to point out that: 1) my PC did not make a real shutdown but a suspension; 2) the correct code I rewrote is:

Public Function LipPCIsOnNew() As String
  Dim EventoLogApp As New System.Diagnostics.EventLog("System")
  Dim OraACCENSIONE As Date, stMachineName As String

  ' search from the end, to find the last boot faster
  For i = EventoLogApp.Entries.Count - 1 To 1 Step -1

     If EventoLogApp.Entries(i).InstanceId.ToString = 1 Then

        OraACCENSIONE = EventoLogApp.Entries(i).TimeGenerated

        stMachineName = EventoLogApp.Entries(i).MachineName.ToString

        Exit For
     End If
  Next

  Return OraACCENSIONE.ToString

End Function

Now everything is ok

Thank you all

Upvotes: -1

Andrew Morton
Andrew Morton

Reputation: 25013

There may be some other source of the last power-on time, but you can use the Windows System Event Log to get the last event from Kernel-Boot:

Function GetLastPowerOn() As DateTime?
    Dim systemEventLog = New EventLog()
    systemEventLog.Log = "System"

    Dim lastPowerOn = systemEventLog.Entries.Cast(Of EventLogEntry).
        Where(Function(eu) eu.Source = "Microsoft-Windows-Kernel-Boot").
        OrderByDescending(Function(ev) ev.TimeGenerated).FirstOrDefault()

    Return lastPowerOn?.TimeGenerated

End Function

I do not know the behaviour for if there is no entry, so I assumed that a Nullable(Of DateTime) would do. If you want to clear your System event log, you could let us know what happens; I don't want to do that.

Unfortunately, it takes ages to return a value (e.g. about 7 seconds on this computer), so you might want to call it asynchronously. Here is an example which uses one button and two labels on a form:

Public Class Form1
    Dim tim As Timer

    Friend Async Function GetLastPowerOnAsync() As Task(Of DateTime?)
        Dim systemEventLog = New EventLog() With {.Log = "System"}
        Dim tsk = Await Task.Factory.StartNew(Function()
                                                  Return systemEventLog.Entries.Cast(Of EventLogEntry).
                                                  Where(Function(eu) eu.Source = "Microsoft-Windows-Kernel-Boot").
                                                  OrderByDescending(Function(ev) ev.TimeGenerated).
                                                  FirstOrDefault()
                                              End Function)

        Return tsk?.TimeGenerated

    End Function

    Sub timTick(sender As Object, e As EventArgs)
        Label1.Text = DateTime.Now.ToString("HH:mm:ss")
    End Sub

    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim lpo = Await GetLastPowerOnAsync()
        If lpo.HasValue Then
            Label2.Text = lpo.Value.ToString("yyyy-MM-dd HH:mm:ss")
        Else
            Label2.Text = "No System event log entry with a source of Microsoft-Windows-Kernel-Boot entry found."
        End If

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        tim = New Timer() With {.Interval = 500}
        AddHandler tim.Tick, AddressOf timTick
        tim.Start()

    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        RemoveHandler tim.Tick, AddressOf timTick
        tim.Dispose()

    End Sub

End Class

Upvotes: 2

Related Questions