Reputation: 37
I am trying to create a batch file that will countdown when activated and logoff of the system. This is for when the user is no longer at the computer. I have come across multiple forums where people are doing this but they log off any time the user is idle for x minutes or seconds. What I have does count down and does log off or cancel and I have it set in the task scheduler to start when the computer has been idle. That part is working fine. What I cannot seem to get to work right is to only perform the countdown if the time is after 6:30 PM (18:30). It has worked once for me but I cannot get it to work anymore.
So what I need in a more specific sequence.
The stuff below seems to be working perfectly as of right now.
Here is my code right now which works, it just doesn't care about what time it is.
TITLE Automatic Log Off Initiated!
mode con:cols=80 lines=1
COLOR CF
@echo off
setlocal enableextensions enabledelayedexpansion
set tm=%time%
:: Test data on lines below.
:: set tm=18:59:59.00
:: set tm=19:00:00.00
:: set tm=19:44:59.00
:: set tm=19:45:00.00
:: set tm=23:59:59.99
set hh=!tm:~0,2!
set mm=!tm:~3,2!
if !hh! LEQ 18 if !mm! LEQ 30 (
exit
)
else goto :begin
:begin
for /l %%N in (600 -1 1) do (
set /a "min=%%N/60, sec=%%N%%60, n-=1"
if !sec! lss 10 set sec=0!sec!
cls
choice /c:1ABCDEFGHIJKLMNOPQRSTUVWXYZ /n /m "Automatically Logging Off in !min!:!sec! - Press any key or move the mouse to cancel" /t 1 /d 1
if not errorlevel 1 goto :break
if errorlevel 2 goto :end
if errorlevel 3 goto :end
if errorlevel 4 goto :end
if errorlevel 5 goto :end
if errorlevel 6 goto :end
if errorlevel 7 goto :end
if errorlevel 8 goto :end
if errorlevel 9 goto :end
if errorlevel 10 goto :end
if errorlevel 11 goto :end
if errorlevel 12 goto :end
if errorlevel 13 goto :end
if errorlevel 14 goto :end
if errorlevel 15 goto :end
if errorlevel 16 goto :end
if errorlevel 17 goto :end
if errorlevel 18 goto :end
if errorlevel 19 goto :end
if errorlevel 20 goto :end
if errorlevel 21 goto :end
if errorlevel 22 goto :end
if errorlevel 23 goto :end
if errorlevel 24 goto :end
if errorlevel 25 goto :end
if errorlevel 26 goto :end
if errorlevel 27 goto :end
)
:break
shutdown /l /f
:end
exit
I have played with it to test the time using different times but it still does not work.
I have also tried using a second IF statement but that did not work.
IF !hh! GTR 18 IF !mm! GTR 30 (
goto :begin
)
Any help is greatly appreciated! Thank you!
Upvotes: 0
Views: 627
Reputation: 80113
set hh=!tm:~0,2!
set mm=!tm:~3,2!
if !hh! LEQ 18 if !mm! LEQ 30 (
exit
)
else goto :begin
Incorrect syntax. The "else" keyword must be on the same line as the close-parenthesis for the if-true
action statement.
What is happening is that this else
clause will produce an error message, but batch then proceeds to the :begin
label anyway and the message is cleared from the screen by the cls
within the for
loop.
The !var!
syntax is unnecessary in this part of the code. It is only required within a code block (ie. parenthesised series of statements.)
Be careful. hh
or mm
may be set with a leading "0", which batch regards as octal hence 08
and 09
are invalid.
In this case, batch will recognise that it can't concert 08
or 09
so it switches to normal (string-comparison) mode and correctly compares the strings to 18
and 30
.
But here's a trap. If you were to replace 30
with 7
then you'd find that 08
and 09
were less than 7
. This is because when you "switch" to string-comparison
mode (actually you don't switch to numeric-comparison mode because one side or the other can't be converted to an integer) the comparison is performed character-by-character from the left, and "0"
is less than "7"
It only appears to work because of the particular number you've chosen don't fall foul of this mechanism. I call it a fail-to-fail scenario. It's quite common - because it hasn't been observed to fail, it's assumed to be working, until one day someone changes something and it breaks...
Next problem is a misunderstanding of if errorlevel
.
IF ERRORLEVEL n
is TRUE if errorlevel
is n or greater than n. IF ERRORLEVEL 0
is therefore always true. IF NOT ERRORLEVEL 1
is a test for errorlevel=0. So is IF %ERRORLEVEL%==0
, except that the former can be used within a block but the latter cannot.
Your code is set up to individually test the other errorlevels. If you were to change the code to
if errorlevel 2 echo TWO&goto :end
if errorlevel 3 echo THREE&goto :end
(look - to save time, don't bother with the reminder)
and insert a pause
before your exit
:end
pause
exit
then you'd see the message produced. Press an alphabetic key, and the report will be TWO
because if errorlevel 2 echo TWO&goto :end
will echo TWO
and go to :end
if errorlevel
is set to 2 or to greater than 2
If you are really using choice
to make a menu, then the correct procedure is to test in reverse-numerical order. It's redundant here because with your code, pressing X
(for instance) will set errorlevel
to 25 and 25>2, so the test for errorlevel
2 will exit the procedure and close the window.
Again, a fail-to-fail scenario.
Upvotes: 1
Reputation: 37
After fiddling a little more I noticed in another file (copy) that I had
:begin
setlocal enableDelayedExpansion
for...
as I looked closely at the two files I noticed the capital letters at the start of the second and third words. I changed this for the code at the top where it says setlocal enableextensions enabledelayedexpansion
and I changed the first letters to be capital setlocal enableExtensions enableDelayedExpansion
which fixed everything and now it cancels and exits if the time is not yet 6:30 pm and if its after 6:30 then it begins the shutdown sequence and it is working beautifully! so thank you for any of your thoughts but I answered it myself! :D
Hopefully this may be helpful to someone else in the future as well!
Upvotes: 0