Color 15
Print "Enter (R)eboot/(S)hutdown";
Input x$: x$ = UCase$(x$)
If x$ = "R" Then
$If WIN Then
x$ = "%windir%\System32\shutdown.exe /r /t 0"
Call ShellSub(x$)
Print "Reboot failed.."
End
$End If
$If LINUX OR MAC Then
x$ = "/sbin/shutdown -r now"
Call ShellSub(x$)
Print "Reboot failed.."
End
$End If
Print "OS not supported.."
End
End If
If x$ = "S" Then
$If WIN Then
x$ = "%windir%\System32\shutdown.exe /s /t 0"
Call ShellSub(x$)
Print "Shutdown failed.."
End
$End If
$If LINUX OR MAC Then
x$ = "/sbin/shutdown -h now"
Call ShellSub(x$)
Print "Shutdown failed.."
End
$End If
Print "OS not supported.."
End
End If
End
' subroutine to shell to dos
Sub ShellSub (x$)
BatchFile$ = "EXTERNAL.BAT"
X = FreeFile
Open BatchFile$ For Output As #X
Print #X, "@ECHO OFF"
Print #X, x$
Print #X, "PAUSE"
Print #X, "EXIT"
Close #X
Shell BatchFile$
End Sub
10-04-2025, 10:25 PM (This post was last modified: 10-04-2025, 10:29 PM by SierraKen.)
I haven't tried it yet, but I've been wondering if this was possible for decades, thank you! Someone can also use TIME$ if they want to run this in the background and reboot the computer at a certain time every day. Although I don't know how much RAM that would take up. It would have to also go in the Windows Startup Apps settings, if someone wanted to it always run on startup. But test the RAM first.
10-05-2025, 10:23 PM (This post was last modified: 10-06-2025, 10:58 PM by eoredson.)
(10-04-2025, 10:25 PM)SierraKen Wrote: I haven't tried it yet, but I've been wondering if this was possible for decades, thank you! Someone can also use TIME$ if they want to run this in the background and reboot the computer at a certain time every day. Although I don't know how much RAM that would take up. It would have to also go in the Windows Startup Apps settings, if someone wanted to it always run on startup. But test the RAM first.
Sure. Don't see why not. Here is a shutdown with a timer:
Code: (Select All)
Rem program to reboot computer PD 2025.
Rem commandline syntax:
Rem hh:mm:ss [-r][-h]
c$ = Read.Command$
c$ = LCase$(c$)
If Len(c$) Then
c$ = LTrim$(RTrim$(c$))
If c$ = "-?" Then
Color 15
Print "Shutdown command line:"
Color 14
Print " hh:mm:ss sets time match."
Print " -r select reboot."
Print " -s select shutdown."
Color 7
End
End If
v = InStr(c$, "-r") ' reboot
If v = 0 Then
v = InStr(c$, "-s") ' shutdown
If v Then
c$ = Left$(c$, v - 1) + Mid$(c$, v + 1)
Reboot = -1
Else
Color 12
Print "Unknown command line. Type Shutdown -? for help."
Color 7
End
End If
Else
c$ = Left$(c$, v - 1) + Mid$(c$, v + 1)
Reboot = -2
End If
' loop until time matches
c$ = LTrim$(RTrim$(c$))
t$ = c$
If ValidTime(t$) Then
Do
_Limit 50
l$ = InKey$
If l$ = Chr$(27) Then End
If t$ = Time$ Then
If Reboot = -1 Then x$ = "R": Exit Do
If Reboot = -2 Then x$ = "S": Exit Do
Exit Do
End If
Loop
Else
Color 12
Print "Unknown command line. Type Shutdown -? for help."
Color 7
End
End If
Else
Color 15
Print "Enter (R)eboot/(S)hutdown";
Input x$: x$ = UCase$(x$)
End If
If x$ = "R" Then
$If WIN Then
x$ = "%windir%\System32\shutdown.exe /r /t 0"
Call ShellSub(x$)
Print "Reboot failed.."
End
$End If
$If LINUX OR MAC Then
x$ = "/sbin/shutdown -r now"
Call ShellSub(x$)
Print "Reboot failed.."
End
$End If
Print "OS not supported.."
End
End If
If x$ = "S" Then
$If WIN Then
x$ = "%windir%\System32\shutdown.exe /s /t 0"
Call ShellSub(x$)
Print "Shutdown failed.."
End
$End If
$If LINUX OR MAC Then
x$ = "/sbin/shutdown -h now"
Call ShellSub(x$)
Print "Shutdown failed.."
End
$End If
Print "OS not supported.."
End
End If
End
' subroutine to shell to dos
Sub ShellSub (x$)
BatchFile$ = "EXTERNAL.BAT"
X = FreeFile
Open BatchFile$ For Output As #X
Print #X, "@ECHO OFF"
Print #X, x$
Print #X, "PAUSE"
Print #X, "EXIT"
Close #X
Shell BatchFile$
End Sub
Rem get command$
Function Read.Command$
Declare Library
Function GetCommandLineA%& ()
End Declare
Dim m As _MEM, ms As String * 1000
a%& = GetCommandLineA
m = _Mem(a%&, Len(ms))
ms = _MemGet(m, m.OFFSET, String * 1000)
If a%& Then
cmd$ = ms
eol = InStr(cmd$, Chr$(0))
If eol Then
cmd$ = Left$(cmd$, eol - 1)
End If
' parse off program name.
eol = InStr(2, cmd$, Chr$(34)) + 1
cmd$ = Mid$(cmd$, eol)
End If
_MemFree m
Read.Command$ = cmd$
End Function
Function ValidTime (Var$)
' hh:mm:ss
Var$ = RTrim$(Var$)
If Len(Var$) <> 8 Then
ValidTime = 0
Exit Function
End If
For Var = 1 To 8
V$ = Mid$(Var$, Var, 1)
Select Case Var
Case 1, 2, 4, 5, 7, 8
If V$ >= "0" And V$ <= "9" Then
Eat$ = ""
Else
ValidTime = 0
Exit Function
End If
Case Else
If V$ <> ":" Then
ValidTime = 0
Exit Function
End If
End Select
Next
H = Int(Val(Mid$(Var$, 1, 2)))
M = Int(Val(Mid$(Var$, 4, 2)))
S = Int(Val(Mid$(Var$, 7, 2)))
If H >= 0 And H <= 23 Then
If M >= 0 And M <= 59 Then
If S >= 0 And S <= 59 Then
ValidTime = -1
Exit Function
End If
End If
End If
ValidTime = 0
End Function
10-08-2025, 03:07 PM (This post was last modified: 10-08-2025, 06:41 PM by SpriggsySpriggs.)
On Windows, I feel like you would just go to Task Scheduler and set up a reboot task there. I think something similar exists in Linux, too. "SYSTEM" might also be better than "END" for this, so your program will exit at the end rather than waiting for a keypress. Since this is running console commands, would make sense to make the program "$CONSOLE:ONLY" so it doesn't take up more space and runs faster. Also, "COMMAND$(n)" exists for parsing the command line without needing to use another declaration of the Win32 API. If you want to stay using GetCommandLineA, you don't need to use a 1,000-character string to store the result. You can do a declare library block for strlen and call it on GetCommandLineA and store the result in a LONG variable.
Then you could set your "ms" string variable to the size by using "SPACE$(n)". You would then use the sub version of "_MemGet". This allows you to use a variable length string with _Mem.
Here is a working test of what I proposed:
Code: (Select All)
Declare Library
Function strlen& (ByVal str As _Offset)
Function GetCommandLineA%& ()
End Declare
Dim As _MEM m
Dim As _Offset a
Dim As String ms
Dim As Long cmdLen: cmdLen = strlen(GetCommandLineA) 'using "test -r -b" as my command line switches for the test in the below screenshot
ms = Space$(cmdLen)
a = GetCommandLineA
m = _Mem(a, cmdLen)
_MemGet m, m.OFFSET, ms
_MemFree m
10-09-2025, 02:08 AM (This post was last modified: 10-10-2025, 02:28 AM by eoredson.)
The following code of yours works:
Code: (Select All)
Declare Library
Function strlen& (ByVal str As _Offset)
Function GetCommandLineA%& ()
End Declare
Dim As _MEM m
Dim As _Offset a
Dim As String ms
Dim As Long cmdLen
cmdLen = strlen(GetCommandLineA)
ms = Space$(cmdLen)
a = GetCommandLineA
m = _Mem(a, cmdLen)
_MemGet m, m.OFFSET, ms
_MemFree m
p = InStr(2, ms, Chr$(34))
p$ = Left$(ms, p)
c$ = Mid$(ms, p + 1)
Print "Program: "; p$
Print "Command: "; c$
Although since the current code already works then I don't need to upgrade it (because it might break)
Code can be quite finicky, that's for sure. I had an issue trying to do the test at first because I had the GetCommandLine declaration in a separate declare library block and QB64 did not like that one bit. Kept failing to compile. I don't remember that being a problem before in the past, but I could be wrong.