1
@echo off

:cancel

    shutdown /a

:shut

    set a=%1

    shutdown -s -f -t %a%

cls

set /p a="the computer will shut in:" %=%

set /a a=%a%*60

if %a%=="a" call :cancel

pasue

call :shut

pause

It is supposed to ask the user for a number. It will take the number and shutdown the computer in x minutes (I Multiplied by 60 to convert to seconds), if the answer is "a" it will cancel the shutdown.
When I start the program, it is asking me infinity times for input and doesn't call shutdown at all
Thanks :)

Dominique
  • 16,450
  • 15
  • 56
  • 112
clavlav12
  • 74
  • 1
  • 7

2 Answers2

5

Looking at your code, I guess, you're confusing "labels" with "Function declarations". There are no functions in batch (at least not like in other languages), just call, goto and "labels"

For the shown task, you don't need any labels at all:

@echo off
set /p a="the computer will shut in:" %=%
if /i "%a%"=="a" shutdown -a & goto :eof
set /a a*=60
shutdown -s -f -t %a%

(Note: you had a logical failure in your code: set /a always returns an Integer (as long as it doesn't produce a syntax error), so it doesn't make sense to compare the variable with the string a after the set /a)

Recommended read: Where does GOTO :EOF return to?

Stephan
  • 53,940
  • 10
  • 58
  • 91
  • Well, the `function` is just a concept, since there're parameters, call and returns, so it can be called `function`. Well, maybe more like `procedure` than function :) – Til Feb 18 '19 at 08:50
  • 3
    @Tiw: yes, it can be used like a function or procedure, and all of us do that (a lot) and even call them functions sometimes, but technically, it isn't. (My personal favorite term is "Subroutine") – Stephan Feb 18 '19 at 08:55
  • I agree, and like your term "Subroutine" :-) – Til Feb 18 '19 at 08:57
1

Try this:

::It's better to comment out @echo off, and only when the .bat works fine and then use it.
::@echo off

cls
set /p a="the computer will shut in:"
::You'll need to put %a% inside quotes too, otherwise it can't be equal when you input a.
if "%a%"=="a" call :cancel & goto :eof

:: equals to set /a a=a*60, and with /a you don't need %
set /a a*=60

:: You forgot the parameter. And the goto :eof is necessary
call :shut %a%
pause && goto :eof

::You need to put functions at last.
:cancel
    shutdown /a
    goto :eof
:shut
    set a=%1
    shutdown -s -f -t %a%

The main problem in your code is the execution flow.
When there's no switch or gotos, it will execute commands from first line to the last line.
(That's why it asked you infinite times, because every time you call :cancel, it will execute from :cancel function to the set /p again.)

You need to put functions below the main codes.
And in the functions, you need to add goto :eof(except the last line since it's alreay end of file).
And after the function calls you need add goto :eof too.

Til
  • 5,150
  • 13
  • 26
  • 34