How to determine last system boot time on Windows asynchronously?

Has anybody yet managed to read the system boot time on Windows? There is no such function in Christian’s plugins as far as I’ve seen.

In a console one can get the system boot time like this:

systeminfo | findstr /C:"System Boot Time"

I did not succeed in calling this from Xojo with the Xojo Shell class or ShellMBS asynchronously. Because this windows command line tool takes some time to deliver results I want to call it in the background. Using the shell class synchronously works - after some seconds I get the boot time.

This is what I’ve done so far:

I subclassed the Shell class

Protected Class Systeminfo Inherits Shell

The constructor runs the method runSysteminfo:

Private Sub runSysteminfo() Dim sh As New Shell sh.Mode = 1 ' asynchronous mode sh.timeout = 5000 sh.execute "C:\\Windows\\System32\\systeminfo.exe" End Sub

The event DataAvaible waits for the shell program to return data:

(Takes the Result from the subclassed Shell and tries to parse to datetime string.)

#tag Event
Sub DataAvailable()
  output = Result
  'output = ReadAll

  Dim rg As New RegEx
  Dim myMatch As RegExMatch

  rg.SearchPattern = "Systemstartzeit:\\s+(\\d{2})\\.(\\d{2})\\.(\\d{4})\\,\\s+(\\d{2})\\:(\\d{2})\\:(\\d{2})"
  myMatch = rg.Search(output)

  Dim dt As New Date

  dt.Day = Val(myMatch.SubExpressionString(1))
  dt.Month = Val(myMatch.SubExpressionString(2))
  dt.Year = Val(myMatch.SubExpressionString(3))
  dt.Hour = Val(myMatch.SubExpressionString(4))
  dt.Minute = Val(myMatch.SubExpressionString(5))
  dt.Second = Val(myMatch.SubExpressionString(6))

  Systemstarttime = dt

End Sub

But: this event never happens. Either I missed some important aspect of the asynchronous shell mode or the tool really does not return it that way (which is unlikely cause it works in synchronous mode).

Has anybody some advice or hint for me?


Guten Morgen, if I may suggest a different approach? Just run in terminal/dos shell

systeminfo > anyfile.tmp

and do the parsing within Xojo on anyfile.tmp. Looks more reliable to me. Maybe you add some kind of timestamp in the filename to prevent any mess with simltuanous calls and explicitly dump this to %TEMP% or %APPDATA% in order to prevent any issues with access rights.

No need for a shell, there’s a system call for that:

Declare Function GetTickCount Lib "Kernel32" () As Integer Dim uptime As Integer = GetTickCount() ' in milliseconds

Why does runSystemInfo create a generic Shell object? That’s the object whose events will be raised, not the Systeminfo subclass. I think you want something more like this:

Protected Class Systeminfo Inherits Shell Sub Constructor() Me.Mode = 1 ' asynchronous mode Me.timeout = 5000 Me.execute "C:\\Windows\\System32\\systeminfo.exe" End Sub

[quote=436885:@Andrew Lambert]No need for a shell, there’s a system call for that:

Declare Function GetTickCount Lib "Kernel32" () As Integer Dim uptime As Integer = GetTickCount() ' in milliseconds[/quote]

This is even better!

[quote=436862:@Oliver Jakoubek] Dim sh As New Shell
You are creating a local shell object that goes out of scope when the event ends. It then ceases to exist, so it cannot raise the DataAvailable event. If you define sh at a wider scope, it would live long enough to give you a result.