Author Topic: How to write Windows shutdown time (when computer shuts down) to a file?  (Read 3739 times)

0 Members and 1 Guest are viewing this topic.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Hello. I'm playing with a text file in which I write the start of the computer startup. The attached program is added to the folder after startup (START -> SHELL: STARTUP), it writes the startup time correctly. How to make it write down the end time correctly? I expected to be able to do this by monitoring the termination of the program with the _EXIT command, but if this program is terminated by the operating system, the Windows shutdown will not be written to the file. Does anyone have an idea? The whole goal of this program is only for information for me, about how many hours a day I spend at the computer...

In this version is as Windows shutdown time writed time in which is this program end. And that is not what i want.

Code: QB64: [Select]
  1. line$ = "Computer started " + DATE$ + " in " + TIME$
  2. ADDRECTOFILE line$
  3.  
  4.  
  5.     _LIMIT 10
  6.  
  7. line$ = "Computer shut down: " + DATE$ + " in " + TIME$
  8. ADDRECTOFILE line$
  9.  
  10.  
  11.  
  12.  
  13. SUB ADDRECTOFILE (record AS STRING)
  14.     ff = FREEFILE
  15.     file$ = "D:\SystemLog.txt"
  16.     IF _FILEEXISTS(file$) THEN
  17.         OPEN file$ FOR INPUT AS #ff
  18.         fg = FREEFILE
  19.         OPEN "SystemLogNew.txt" FOR OUTPUT AS #fg
  20.         WHILE NOT EOF(ff)
  21.             LINE INPUT #ff, text$
  22.             PRINT #fg, text$
  23.         WEND
  24.             PRINT #fg, record$
  25.         CLOSE ff, fg
  26.         KILL file$
  27.         NAME "SystemLogNew.txt" AS file$
  28.     ELSE
  29.         OPEN file$ FOR OUTPUT AS #ff
  30.         PRINT #ff, "LOG file record - alfa basic version. First record: " + DATE$
  31.         PRINT #ff, record$
  32.         CLOSE ff
  33.     END IF
  34.  

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
@Petr

Consult this link. I think it may point you in the right direction: https://www.apriorit.com/dev-blog/413-win-api-shutdown-events
I'd help you but right now I'm still working on Task Dialogs
Shuwatch!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Thanks for reply, @SpriggsySpriggs  i try do some tests with it.
Thank you.


Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
@Petr I'm in the process of converting their sample code for a shutdown logger to QB64. Here is my progress so far:

Code: QB64: [Select]
  1.  
  2. Const SHUTDOWN_NORETRY = &H00000001
  3. Const IDI_APPLICATION = 32512
  4. Const IDC_ARROW = 32512
  5. Const COLOR_WINDOW = 5
  6.  
  7.     As Long x, y
  8.  
  9. Type MSG
  10.     As _Offset hwnd
  11.     As _Unsigned Long message
  12.     As _Unsigned _Offset wParam
  13.     As _Offset lParam
  14.     As Long time
  15.     As POINT pt
  16.     As Long lPrivate
  17.  
  18. Type WNDCLASSEX
  19.     As _Unsigned Long cbSize, style
  20.     As _Offset lpfnWndProc
  21.     As Long cbClsExtra, cbWndExtra
  22.     As _Offset hInstance, hIcon, hCursor, hbrBackground, lpszMenuName, lpszClassName, hIconSm
  23.  
  24.     Function GetProcessShutdownParameters%% (ByVal lpdwLevel As _Offset, Byval lpdwFlags As _Offset)
  25.     Sub SetProcessShutdownParameters (ByVal dwLevel As Long, Byval dwFlags As Long)
  26.     Function LoadIcon%& Alias "LoadIconA" (ByVal hInstance As _Offset, Byval lpIconName As _Offset)
  27.     Function LoadCursor%& Alias "LoadCursorA" (ByVal hInstance As _Offset, Byval lpCursorName As _Offset)
  28.     Function RegisterClassEx% Alias "RegisterClassExA" (ByVal wndclassex As _Offset)
  29.     Function GetLastError& ()
  30.  
  31.     Function WindowProcCallback%& ()
  32.  
  33.     Function MAKEINTRESOURCE%& Alias "MAKEINTRSC" (ByVal i As Long)
  34.  
  35. Dim Shared As String className: className = "ShutdownWin" + Chr$(0)
  36.  
  37. Dim As WNDCLASSEX wc
  38. Dim As MSG Msg
  39.  
  40. Dim As Long dwLevel: dwLevel = 0
  41. Dim As Long dwFlags: dwFlags = 0
  42.  
  43. If GetProcessShutdownParameters(_Offset(dwLevel), _Offset(dwFlags)) Then
  44.     SetProcessShutdownParameters dwLevel, SHUTDOWN_NORETRY
  45.  
  46. 'Step 1: Registering the Window Class
  47. wc.cbSize = Len(wc)
  48. wc.style = 0
  49. wc.lpfnWndProc = WindowProcCallback
  50. wc.cbClsExtra = 0
  51. wc.cbWndExtra = 0
  52. wc.hInstance = 0
  53. wc.hIcon = LoadIcon(0, MAKEINTRESOURCE(IDI_APPLICATION))
  54. wc.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW))
  55. wc.hbrBackground = COLOR_WINDOW + 1
  56. wc.lpszMenuName = 0
  57. wc.lpszClassName = _Offset(className)
  58. wc.hIconSm = LoadIcon(0, MAKEINTRESOURCE(IDI_APPLICATION))
  59.  
  60. If RegisterClassEx(_Offset(wc)) = 0 Then
  61.     Print "RegisterClassEx failed:"; GetLastError
  62. Else Print "OK"
  63.  
  64. Function WndProc%& (hwnd As _Offset, msg As _Unsigned Long, wParam As _Unsigned _Offset, lParam As _Offset)
  65.     Select Case msg
  66.     End Select
Shuwatch!

Offline euklides

  • Forum Regular
  • Posts: 128
    • View Profile
Batch/dos commands ending with :  shutdown /s

QB64: Shell _Hide "shutdown /s"   


Search windows "shutdown" command on the net for more options 
Why not yes ?

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
@euklides He wants to catch a shutdown, not cause one
Shuwatch!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Windows already keeps a log of start up and shutdown times and events.  Just use Event Viewer to search them out, as wanted.

If what you want instead is to view only the timestamp of the last shutdown, copy and paste the code below at the CMD window and then press Enter:

Code: [Select]
wevtutil qe system “/q:*[System [(EventID=1074)]]” /rd:true /f:text /c:1 | findstr /i “date”
If that’s what you’re looking for, just shell to it and pipecom the result back to your program.

https://www.maketecheasier.com/see-pc-startup-and-shutdown-history-in-windows/
« Last Edit: July 03, 2021, 02:11:24 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
@Petr The code works. I finally got it to catch Windows shutdowns and log them. Here is the code:

Code: QB64: [Select]
  1.  
  2. Const SHUTDOWN_NORETRY = &H00000001
  3. Const IDI_APPLICATION = 32512
  4. Const IDC_ARROW = 32512
  5. Const COLOR_WINDOW = 5
  6. Const WS_EX_CLIENTEDGE = &H00000200
  7. Const WS_OVERLAPPED = &H00000000
  8. Const WS_CAPTION = &H00C00000
  9. Const WS_SYSMENU = &H00080000
  10. Const WS_THICKFRAME = &H00040000
  11. Const WS_MINIMIZEBOX = &H00020000
  12. Const WS_MAXIMIZEBOX = &H00010000
  13. Const WS_OVERLAPPEDWINDOW = WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX
  14. Const CW_USEDEFAULT = &H80000000
  15. Const SW_SHOWMINIMIZED = 2
  16.  
  17. Const WM_CLOSE = &H0010
  18. Const WM_DESTROY = &H0002
  19. Const WM_POWERBROADCAST = &H0218
  20. Const WM_QUERYENDSESSION = &H0011
  21.  
  22. Const PBT_APMSUSPEND = &H0004
  23. Const ENDSESSION_LOGOFF = &H80000000
  24.  
  25.     As Long x, y
  26.  
  27. Type MSG
  28.     As _Offset hwnd
  29.     As _Unsigned Long message
  30.     As _Unsigned _Offset wParam
  31.     As _Offset lParam
  32.     As Long time
  33.     As POINT pt
  34.     As Long lPrivate
  35.  
  36. Type WNDCLASSEX
  37.     As _Unsigned Long cbSize, style
  38.     As _Offset lpfnWndProc
  39.     As Long cbClsExtra, cbWndExtra
  40.     As _Offset hInstance, hIcon, hCursor, hbrBackground, lpszMenuName, lpszClassName, hIconSm
  41.  
  42.     Function GetProcessShutdownParameters%% (ByVal lpdwLevel As _Offset, Byval lpdwFlags As _Offset)
  43.     Sub SetProcessShutdownParameters (ByVal dwLevel As Long, Byval dwFlags As Long)
  44.     Sub ShutdownBlockReasonCreate (ByVal hWnd As _Offset, Byval lpwszReason As _Offset)
  45.     Function DefWindowProc%& (ByVal hWnd As _Offset, Byval Msg As _Unsigned Long, Byval wParam As _Unsigned _Offset, Byval lParam As _Offset)
  46.     Sub PostQuitMessage (ByVal nExitCode As Long)
  47.     Function LoadCursor%& (ByVal hInstance As _Offset, Byval lpCursorName As _Offset)
  48.     Function LoadIcon%& (ByVal hInstance As _Offset, Byval lpIconName As _Offset)
  49.     Function RegisterClassEx% (ByVal wndclassex As _Offset)
  50.     Function CreateWindowEx%& (ByVal dwExStyle As Long, Byval lpClassName As _Offset, Byval lpWindowName As _Offset, Byval dwStyle As Long, Byval X As Long, Byval Y As Long, Byval nWidth As Long, Byval nHeight As Long, Byval hWndParent As _Offset, Byval wMenu As _Offset, Byval hInstance As _Offset, Byval lpParam As _Offset)
  51.     Sub ShowWindow (ByVal hWnd As _Offset, Byval nCmdShow As Long)
  52.     Sub UpdateWindow (ByVal hWnd As _Offset)
  53.     Function GetMessage%% (ByVal lpMsg As _Offset, Byval hWnd As _Offset, Byval wMsgFilterMin As _Unsigned Long, Byval wMsgFilterMax As _Unsigned Long)
  54.     Sub TranslateMessage (ByVal lpMsg As _Offset)
  55.     Sub DispatchMessage (ByVal lpMsg As _Offset)
  56.     Function GetModuleHandle%& (ByVal lpModulename As _Offset)
  57.     Sub DestroyWindow (ByVal hWnd As _Offset)
  58.     Function GetLastError& ()
  59.  
  60.     Function MAKEINTRESOURCE%& Alias "MAKEINTRSC" (ByVal i As Long)
  61.  
  62.     Function WindowProcCallback%& ()
  63.  
  64. If _FileExists("ShutdownLog.log") = 0 Then
  65.     Open "ShutdownLog.log" For Output As #1
  66.     Close #1
  67.  
  68. WriteLog "Computer has finished startup at " + Time$ + " on " + Date$ 'put program in SHELL:STARTUP to catch this behavior
  69.  
  70. Dim Shared As String className: className = "ShutdownWin" + Chr$(0)
  71.  
  72. Dim As WNDCLASSEX wc
  73. Dim As _Offset hwnd, hInstance
  74. Dim As MSG Msg
  75.  
  76. Dim As Long dwLevel: dwLevel = 0
  77. Dim As Long dwFlags: dwFlags = 0
  78. hInstance = GetModuleHandle(0)
  79.  
  80. If GetProcessShutdownParameters(_Offset(dwLevel), _Offset(dwFlags)) Then
  81.     SetProcessShutdownParameters dwLevel, SHUTDOWN_NORETRY
  82.  
  83. 'Step 1: Registering the Window Class
  84. wc.cbSize = Len(wc)
  85. wc.style = 0
  86. wc.lpfnWndProc = WindowProcCallback
  87. wc.cbClsExtra = 0
  88. wc.cbWndExtra = 0
  89. wc.hInstance = hInstance
  90. wc.hIcon = LoadIcon(0, MAKEINTRESOURCE(IDI_APPLICATION))
  91. wc.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW))
  92. wc.hbrBackground = COLOR_WINDOW + 1
  93. wc.lpszMenuName = 0
  94. wc.lpszClassName = _Offset(className)
  95. wc.hIconSm = LoadIcon(0, MAKEINTRESOURCE(IDI_APPLICATION))
  96.  
  97. If RegisterClassEx(_Offset(wc)) = 0 Then
  98.     Print "RegisterClassEx failed:"; GetLastError
  99.     End
  100.     'Else Print "OK"
  101.  
  102. Dim As String clientTitle: clientTitle = "Shutdown GUI Test" + Chr$(0)
  103. 'Step 2: Creating the Window
  104. hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, _Offset(className), _Offset(clientTitle), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, 0, 0, hInstance, 0)
  105.  
  106. If hwnd = 0 Then
  107.     Print "Window Creation Failed:"; GetLastError
  108.     End
  109.  
  110. ShowWindow hwnd, SW_SHOWMINIMIZED
  111. UpdateWindow hwnd
  112.  
  113. While GetMessage(_Offset(Msg), 0, 0, 0) > 0
  114.     TranslateMessage _Offset(Msg)
  115.     DispatchMessage _Offset(Msg)
  116.  
  117. System Val(Str$(Msg.wParam))
  118. 'End
  119.  
  120. Function WndProc%& (hwnd As _Offset, msg As _Unsigned Long, wParam As _Unsigned _Offset, lParam As _Offset)
  121.     Select Case msg
  122.         Case WM_CLOSE
  123.             DestroyWindow hwnd
  124.             Exit Case
  125.         Case WM_DESTROY
  126.             PostQuitMessage 0
  127.             Exit Case
  128.         Case WM_POWERBROADCAST
  129.             If wParam = PBT_APMSUSPEND Then
  130.                 WriteLog "Computer suspended at " + Time$ + " on " + Date$
  131.             End If
  132.             Exit Case
  133.         Case WM_QUERYENDSESSION
  134.             If lParam = 0 Then
  135.                 WriteLog "Computer started shutting down at " + Time$ + " on " + Date$
  136.                 Dim As String blockReason: blockReason = ANSIToUnicode("Shutdown logger is running..." + Chr$(0))
  137.                 ShutdownBlockReasonCreate hwnd, _Offset(blockReason)
  138.                 If (lParam And ENDSESSION_LOGOFF) = ENDSESSION_LOGOFF Then
  139.                     WriteLog "User is logging off at " + Time$ + " on " + Date$
  140.                 End If
  141.                 Exit Case
  142.             End If
  143.         Case Else
  144.             WndProc = DefWindowProc(hwnd, msg, wParam, lParam)
  145.             Exit Function
  146.     End Select
  147.     WndProc = 0
  148.  
  149. Sub WriteLog (logText As String)
  150.     Open "ShutdownLog.log" For Append As #1
  151.     Print #1, logText
  152.     Close #1
  153.  
  154. '$INCLUDE:'unicodetoansi.bas'
« Last Edit: July 04, 2021, 01:58:08 pm by SpriggsySpriggs »
Shuwatch!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Thank you all very much. I didn't know about the solution @SMcNeill  was writing about (it might have occurred to me, but it didn't occur to me), thank you Steve. @SpriggsySpriggs , thank you very much. You are a magician with dynamic libraries. Such a QB64 - librarian - David Copperfield. I will try both versions. Definitely these paths are worth exploring. Thanks a lot.