DomCan
DomCan

Reputation: 37

Batch Log Off Countdown

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

Answers (2)

Magoo
Magoo

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

DomCan
DomCan

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

Related Questions