1

I am very new to batch, so please be easy. That being said, I am attempting to write a batch file that every few minutes will execute a VBScript that updates information on our network. Currently I have:

@ECHO OFF
REM Run VBScript
GOTO SKIP01
:LOOP    
wscript "C:\Users\Desktop\RenameMove.vbs"
GOTO SKIP01
:
:
:SKIP01
REM 3 Min Delay
PING 1.1.1.1 -n 10 -w 18000 >NUL
IF HOUR:%time:~0,5% <09:44
GOTO SKIP01
IF HOUR:%time:~0,5% >16:00
GOTO SKIP01
IF HOUR:%time:~0,5% >=09:45
GOTO LOOP

Currently the window will open for a minute or two, then it just closes. If I run the above after removing the first GOTO SKIP01, the VBScript executes perfectly. Then there is a delay and the window closes. I imagine that it is everything under :SKIP01 that is causing the problem. The function I am trying to achieve is for the .BAT file to continuously loop a delay between the hours of 16:01 - 09:44. Then run the VBScript every 3 minutes from 09:45 - 16:00. Searching the forums I have yet to find anything to help. As I said, I am very new to Batch.

RE: My last comment below:

@ECHO OFF
setlocal enableextensions disabledelayedexpansion
set delay=180
set "startTime=09:45"
set "endTime=16:00"

:LOOP
set "now=%time: =0%"
:: ECHO It's %now%, waiting %delay% seconds
echo %date% %time% >> log.txt
if "%now%" geq "%startTime%:00,00" ( 
GOTO LOOP2
)

:LOOP2
set "now=%time: =0%"
:: ECHO It's %now%, waiting %delay% seconds
echo %date% %time% >> log.txt

if "%now%" lss "%endTime%:00,00" ( 

::       ECHO Start MSAccess
GOTO CALLVBS
)

:WAIT
REM 10 second delay
PING 127.0.0.1 -n %delay% >REM
GOTO LOOP


:CALLVBS    
echo Time to Move!
wscript "C:\Users\ljs\Desktop\Stock_Automation_DO_NOT_EDIT\RenameMove.vbs" 
GOTO WAIT
SanLuka
  • 125
  • 2
  • 13
  • 1
    Not sure why you would not do this with a Windows Scheduled Task. None of your `IF` commands are valid syntax and the `GOTO` should be up on the same line as your IF command as well. – Squashman Jan 25 '16 at 19:17
  • 1
    1. Because I would like to know how to do it via Batch 2. I figured it would be much less time consuming to have a Batch file auto run versus setting up multiple tasks for all business days of the year. – SanLuka Jan 25 '16 at 19:56
  • How would I go about putting the `IF` commands in valid syntax? – SanLuka Jan 25 '16 at 19:58
  • Not understanding how your existing script takes into consideration all the business days of the year. – Squashman Jan 25 '16 at 20:00
  • Well you could start by opening up a cmd prompt and typing: `IF /?`. That will show you the correct operators you can use with the `IF` command. The greater than and less than symbols are not valid because those are used for input and output streams. – Squashman Jan 25 '16 at 20:03

1 Answers1

1

I renamed some things so it made more sense to me, but here is a working version. there are variables at the top for the delay (in seconds) and the start and end time for the window. I also modified your ping delay to something more simple, in my opinion.

Remove the echos for production and add the vbscript file to the CALLVBS function.

@ECHO OFF
setlocal enableextensions disabledelayedexpansion
set delay=180
set "startTime=09:45"
set "endTime=16:00"

:LOOP
  set "now=%time: =0%"
  ECHO It's %now%, waiting %delay% seconds
  if "%now%" geq "%startTime%:00,00" ( 
    ECHO It's after %startTime%
    if "%now%" lss "%endTime%:00,00" ( 
        ECHO And it's before %endTime%
        GOTO CALLVBS
    )
  )

:WAIT
  REM 10 second delay
  PING 127.0.0.1 -n %delay% >REM
  GOTO LOOP

:CALLVBS    
  echo It's time!
  REM Call VBS here
  GOTO WAIT

Here's what's happening, as explained by someone who barely knows what he's talking about:

ABOUT GOTO

First you need to know that batch files process line-by-line from top to bottom, unless it encounters certain statements like if, for or goto, the last of which being the one we are concerned with here. If the interpreter encounters a GOTO command, it will go to the corresponding label and resume processing code line by line until it finds another GOTO or gets to the end of the file.

SIMPLE EXAMPLE

@echo off
GOTO :FRUITS

:COLORS
echo Red
echo Green
GOTO :END

:FRUITS
echo Apple
echo Banana
GOTO :COLORS

:END
echo Done!

This outputs the following:

Apple
Banana
Red
Green
Done!

BREAKDOWN

Set up variables

@ECHO OFF
setlocal enableextensions disabledelayedexpansion
set delay=180
set "startTime=09:45"
set "endTime=16:00" 

This sets some settings and creates some variables for use later. The variables should be self explanatory but I can elaborate if you want.

check the time

01. :LOOP
02.   set "now=%time: =0%"
03.   ECHO It's %now%, waiting %delay% seconds
04.   if "%now%" geq "%startTime%:00,00" ( 
05.      ECHO It's after %startTime%
06.      if "%now%" lss "%endTime%:00,00" ( 
07.          ECHO And it's before %endTime%
08.          GOTO CALLVBS
09.     )
10.   )

This is our "loop". :LOOP denotes what is basically a labeled section of code that we can go back to any time we want. I called it LOOP because it is the section we are doing over and over. It may have been more accurate to call it :CHECKTIME or something similar, as that's what it does.
The label means absolutely nothing to the interpreter so calling it "LOOP" doesn't mean it's going to repeat. This may be the biggest source of confusion.

Here is a step-by-step of what each line on this block does (not processing conditions, just line by line):

  1. Get the current time.
  2. Output the current time
  3. Compare the current time to the endTime variable.
  4. Output the result.
  5. Compare the current time to the startTimevariable.
  6. Output the result.
  7. Goto the CALLVBS section of code

Note that I could have put GOTO WAIT at the end of this block and that might make more sense, but since :WAIT is the next block of code that's what will process next anyway, so the GOTO would be superfluous! This may be a second point of confusion.

Wait a bit

:WAIT
  REM 10 second delay
  PING 127.0.0.1 -n %delay% >REM
  GOTO LOOP

This is the section of code that simply waits the specified number of seconds. It does this using the ping command which is common for batch programming since there is no built-in delay or sleep command like other languages have. The first line is simply a comment, REM means "Remove" (I think) and is how you comment out lines of code in batch. As a matter of fact, I should have removed this since it's not 10 seconds anyway :). The second line pings the localhost 180 times (or whatever the delay variable is set to). The >REM part means it outputs the results of the ping to, well, I've never seen "REM" here. Usually you would output it to nul but either way, it's making sure you don't see the 180 ping results. Now, the 3rd line tells the processor to go back to the :LOOP label. No matter what. After the ping, it does the :LOOP section code again.

Execute your vbscript

:CALLVBS    
  echo It's time!
  REM Call VBS here
  GOTO WAIT

This is the :CALLVBS section of code. First it outputs "It's time!". The second line is again, a comment. As you know, you replace this with your vbscript. After this, the interpreter is told to go to the :WAIT section of code. Again, it will always do this, no matter what, after executing the line above it.

  • Actually I spoke too soon. It keeps looping Saying it is Before the start time and also that is is after the end time. Any thoughts? – SanLuka Jan 26 '16 at 15:05
  • I made some minor formatting changes that I didn't test, let me double check –  Jan 26 '16 at 15:06
  • Updated, try it now. Sorry about that. What happened was I moved the pause to after the execution so that it would call the VBS as soon as it was in the window instead of waiting 3 minutes THEN calling it. That caused the logic error. I broke it out into separate LOOP and WAIT functions. –  Jan 26 '16 at 15:10
  • 1
    Thanks for the knowledge! – SanLuka Jan 26 '16 at 20:04
  • Thanks for the script. Just wondering, It appears (to my untrained eyes) that this simply echo's out based on the time. It looks like it would still call the VBS regardless. I've made some adjustments, both to try to meet what I am looking for, and also to try to learn. To make this truly work, wouldn't I need to create two of the `:LOOP` where if the current time was inside of the two times it would call `:CALLVBS` and if it was outside the two times it would call `:WAIT`? – SanLuka Feb 02 '16 at 20:09
  • 1
    Okay, I just made a crazy edit. Partially for you and partially for me. I think the two sources of confusion are as follows: 1) :LOOP is just a name. It could be called :APPLESAUCE. It does not tell the interpreter to repeat the section. 2) I could have put a GOTO WAIT after the LOOP section of code. This may have made more sense but is pointless since the next code in line is the WAIT section anway. Please let me know if this doesn't answer your two questions. –  Feb 02 '16 at 21:28
  • I wish I could 100 up your answer, as it is the most complete, informative, and helpful answer I have ever gotten on this site. I now better understand the mechanics of `batch` and gained insight on how I can use this going forward. – SanLuka Feb 03 '16 at 13:52
  • Now my next question would be, how to set something similar to an `and` statement within the `if`'s (pardon my Excel function thinking brain). So that it would only continue `if` it was after `startTime` `and` before `endTime`. Is this possible? Or am I over complicating it? – SanLuka Feb 03 '16 at 14:01
  • 1
    It's not technically possible to use `AND` and `OR` operators which is why I nested the ifs. See this question for more info and workarounds: http://stackoverflow.com/questions/2143187/logical-operators-and-or-in-dos-batch –  Feb 03 '16 at 14:02
  • 1
    Keep in mind that it won't process the code below the second `IF` unless both comparisons are true. So `IF x (IF y (launchvbs))` is effectively the same as `IF x AND y (launchvbs)` –  Feb 03 '16 at 14:05
  • I think I finally understand. I just switched the `ECHO`'s so that it will only continue if it is within that time window. – SanLuka Feb 03 '16 at 14:17
  • Lucas, I saw your edit and rejected it. Give me a second to explain why –  Feb 03 '16 at 14:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/102486/discussion-between-lucas-sitterly-and-devilsadvocate). – SanLuka Feb 03 '16 at 14:18