Could use some help with how to do batch code?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
batchfile
Posts: 13
Joined: 09 Apr 2013 01:27

Re: Could use some help with how to do batch code?

#16 Post by batchfile » 09 Apr 2013 14:39

Endoro wrote:I'm not really sure about your needs- but you can try this.

It does:
- get the current Julian Day
- get the last stored Julian Day from a .sav file, build one if it not exists
- check the difference between today and the stored Julian Day
- if the difference is greater than 29 it might start your task if you put the code in and the current Julian Day is stored
- the Julian Day function is from here.

Code: Select all

@echo off&setlocal
set "fsave=%~dpn0.sav"

call:JDNtoday cJDN
call:getsaveJDN sJDN
if not defined sJDN goto:saveJDN
set /a days=%cJDN%-%sJDN%
echo(%days% day(s^) have passed.
if %days% gtr 29 (
   rem start task B here
   echo(starting task B now ...
   rem store the new date in %~dpn0.sav
   call:saveJDN
)
goto:eof

:saveJDN
>"%fsave%" echo(%cJDN%&& (echo(Date saved & goto:eof) || echo ERROR date NOT in "%fsave%" saved & goto:eof
goto:eof

:getsaveJDN
setlocal
if exist "%fsave%" for /f "usebackq" %%i in ("%fsave%") do set "JDN=%%i"
endlocal& set "%1=%JDN%"
exit /b

:JDNtoday
setlocal
for /f "tokens=2*" %%a in ('reg query "HKCU\Control Panel\International" /v sShortDate^|find "REG_SZ"') do set "ssShortDate=%%b"
reg add "HKCU\Control Panel\International" /f /v sShortDate /d "dd MM yyyy" >nul
set "cdate=%date%"
reg add "HKCU\Control Panel\International" /f /v sShortDate /d "%ssShortDate%" >nul
for /f "tokens=1-3" %%i in ("%cdate%") do set "day=0%%i"&set "month=0%%j"&set "year=%%k"
set "day=%day:~-2%"
set "month=%month:~-2%"
call:DateToJDN %day%.%month%.%year% JDN
endlocal& set "%1=%JDN%"
exit /b


:DateToJDN dd.mm.yyyy jdn=
setlocal
set date=%1
set /A yy=%date:~-4%, mm=1%date:~-7,2% %% 100, dd=1%date:~-10,2% %% 100
set /A a=mm-14, jdn=(1461*(yy+4800+a/12))/4+(367*(mm-2-12*(a/12)))/12-(3*((yy+4900+a/12)/100))/4+dd-32075
endlocal & set %2=%jdn%
exit /B


endlocal



Ok, so as intermediate batch coder I'm seeing instead of check.bat running the program it self, your code triggers the Task B and all I need to do is re-create Task B and your code starts over to new Task B beginning date and thus comparisons and action or no action

Is that correct?

I know you put remarks in code but can you walk me through it a little please?

Also can or are we deleting the Check.sav after Check.bat has done the coding to detect difference and run task B which runs program?

Thanks you are so helpful and I really like seeing advanced batch code to learn from

@Squashman

Thanks for coming back ;) I still wish for it to be automated so user is free from doing anything manually. I actually had a .xml file that set that setting but don't want to have any rogue files in this endevour, just one .cmd file with everything

My initial desires we're to indeed query the scheduled task or do queries in general and your idea of NEXT RUN TIME is an great idea!

Here is the code to create and query a task schedule which shows exact time/date Task B will run!

Code: Select all

schtasks /create /tn "TaskB" /tr "%SystemDrive%\Program.exe" /sc daily /mo 30 /ru "" /f >NUL


Code: Select all

schtasks /query /tn "TaskB" 2>NUL | FINDSTR "TaskB"


Image

Let me see if I can redefine the logic for this batch not so much for you guys but to talk out loud for myself so I can better understand

Code: Select all

1. Check.bat file contains code to track dates in a universal region way and in comparing them, if past time/date Task B runs program.exe then check.bat just exits
2. After that Task B is re-created so new date will be available for comparison and check.bat code deletes check.sav and does new check.sav

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Could use some help with how to do batch code?

#17 Post by abc0502 » 09 Apr 2013 15:34

I have a suggestion,
You don't set a specific time the task run in every 30 days, then why you don't just skip the task scheduled, it make too many troubles, you can't take the query as it might be different from system to other like xp and 7 and you must make the exe file create some sort of a log or create/update a filet to check it's last time it was executed.

Just make one batch that start on every time windows start (by registry or by start up folder), and it keeps a log file for the last time it executed the exe application,
So every start it check if it passed the 30 days or not, if so it run the exe file, if not it just exit.

Is that ok with you :?:

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: Could use some help with how to do batch code?

#18 Post by Squashman » 09 Apr 2013 15:41

Endoro wrote:- get the last stored Julian Day from a .sav file, build one if it not exists

That doesn't seem to make sense to me. The program he is running would have to build some type of log file with the date in it. I don't see how you can build the saved date with the batch file that checks to see if the program ran.

For example: Let say the program just ran 10 days ago. He runs your batch file for the first time and it creates a Log file with today's date. Twenty days from today the program would run again and 10 days after that your batch file will force it to run again.

Endoro
Posts: 244
Joined: 27 Mar 2013 01:29
Location: Bozen

Re: Could use some help with how to do batch code?

#19 Post by Endoro » 09 Apr 2013 15:59

As you can see, the batch doesn't (and can't) check when the last task has been running. This belongs to the user. The batch can (and does) check when itself has been running. And it can trigger the task.

Patches are welcome :)

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: Could use some help with how to do batch code?

#20 Post by Squashman » 09 Apr 2013 16:08

Endoro wrote:As you can see, the batch doesn't (and can't) check when the last task has been running. This belongs to the user. The batch can (and does) check when itself has been running. And it can trigger the task.

Patches are welcome :)


Ah I see now. You are basically using your batch file to do everything and disregarding the scheduled task that he has setup. I believe he wants us to check to see if the scheduled task has run and if it didn't then kick it off.

batchfile
Posts: 13
Joined: 09 Apr 2013 01:27

Re: Could use some help with how to do batch code?

#21 Post by batchfile » 09 Apr 2013 16:26

abc0502 wrote:I have a suggestion,
You don't set a specific time the task run in every 30 days, then why you don't just skip the task scheduled, it make too many troubles, you can't take the query as it might be different from system to other like xp and 7 and you must make the exe file create some sort of a log or create/update a filet to check it's last time it was executed.

Just make one batch that start on every time windows start (by registry or by start up folder), and it keeps a log file for the last time it executed the exe application,
So every start it check if it passed the 30 days or not, if so it run the exe file, if not it just exit.

Is that ok with you :?:


To be exact this Check.bat I need is to be run only on W7

I would love the single use of the Task A to be only one used at startup but what if user is on comp all the time and never shuts down hence never starts up for Task A to call Check.bat! I have to ideally sandwich the program.exe running if comp is on or upon boot

Thanks for your time to post :D

@Squashman

To provide more information, I create a folder in %SystemDrive%\Folder that will hold all files that are triggered by Task A. This includes:

1. Backup via query of date Task B was created for comparison and action or not towards Task B to run
2. Check.bat which performs all actions in taking note/doing query to determine every time Task B is created with it's date/time to run

Remember Task B when it runs gets re-created and thus Check.bat must take that into account

So I:

1. Create Task B and Task A
2. Install folder in %SystemDrive% for all files used to get date/time such as Check.bat or ?.sav
3. Normally when user has comp on during Task B trigger time program.exe will run
4. If comp is not on then Task B will never run so Task A is needed to fill the gap - Is program.exe running at least at boot > 1 day past Task B trigger date

p.s. I can either go with Check.bat running program.exe or calling task B to do it but to save code probably just do run task B

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: Could use some help with how to do batch code?

#22 Post by Squashman » 09 Apr 2013 16:51

batchfile wrote:Remember Task B when it runs gets re-created and thus Check.bat must take that into account

This confuses the hell out of me.
Are you saying the executable that Task B runs recreates the Scheduled task? If that is the case then it would also have to delete the previous scheduled task.
Which makes no sense based on the code you used to orginally create the scheduled task.

Code: Select all

schtasks /create /tn "TaskB" /tr "%SystemDrive%\Program.exe" /sc daily /mo 30 /ru "" /f >NUL

batchfile
Posts: 13
Joined: 09 Apr 2013 01:27

Re: Could use some help with how to do batch code?

#23 Post by batchfile » 09 Apr 2013 17:24

Squashman wrote:
batchfile wrote:Remember Task B when it runs gets re-created and thus Check.bat must take that into account

This confuses the hell out of me.
Are you saying the executable that Task B runs recreates the Scheduled task? If that is the case then it would also have to delete the previous scheduled task.
Which makes no sense based on the code you used to orginally create the scheduled task.

Code: Select all

schtasks /create /tn "TaskB" /tr "%SystemDrive%\Program.exe" /sc daily /mo 30 /ru "" /f >NUL


For W7 no task delete is necessary at least the way I do it, just create it again and poof new task

I have worked with experiences of needing to delete task before creation task but this is not one of them

It is just a technique I designed to keep things in sync after program.exe runs so new date is available for Check.bat to do it's thing.

So Check.bat would re-create task after it either does it's own running program.exe or call task B to run program.exe (Both will work just it's less code to run task B)

So in jest all that changes is new future date to run task B, nothing else...

Hope I said it clearly?

Thanks SM

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: Could use some help with how to do batch code?

#24 Post by Squashman » 09 Apr 2013 17:32

I am tapping out on this one. I have no idea what you are trying to do and why. If you are recreating the scheduled task which you can do by using the /F switch to force it then you might as well build an XML file to set the "Run task if it was missed" option. The Scheduler service polls every 10 minutes to see if missed tasks still need to run.

batchfile
Posts: 13
Joined: 09 Apr 2013 01:27

Re: Could use some help with how to do batch code?

#25 Post by batchfile » 09 Apr 2013 17:54

Squashman wrote:I am tapping out on this one. I have no idea what you are trying to do and why. If you are recreating the scheduled task which you can do by using the /F switch to force it then you might as well build an XML file to set the "Run task if it was missed" option. The Scheduler service polls every 10 minutes to see if missed tasks still need to run.


I understand and am very appreciative you even responded one time as I'm not as gifted as you and others although my ideas are fun and manifest after some time figuring things out

I like one .cmd file to do everything like create the independent Check.bat files thus leaving windows to keep track or do actions rather than having multiple rogue files to call/compile into .exe and believe it or not the task scheduler setting is buggy in others and my testing or it would have been greater consideration for doing API that could have compiled multiple .exe's to call/run but I like the simplicity, elegance and lightweight aspects of a batch file which is why I joined DOS BF cause I saw such enthusiasm for cmd console programming

I also don't want to wait 10 minutes which if I can understand how to do regionally universal dates for different OS languages and compare initial date and current date, then act or not it will be instant upon startup then redo task B and start the whole date comparison code again based on new Task B trigger date

:wink:

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Could use some help with how to do batch code?

#26 Post by abc0502 » 09 Apr 2013 18:13

Ok, try this, i hope that what you need :roll:

There will be no check.bat or other batch files, just one.
Put that batch in the start-up folder or in the registry, and when it runs it do the following:

Code: Select all

Check to see if a log file exist:
    [+] IF not that means it is the first time and it will create a log file with a number ( will explain that later ), then schedule the
         task to run after 30 days ( will not run the application, if you need it to say it ).
    [+] IF the file exist that means it was run before and will check the log file as following:
         > get the number from the log file.
         > get the current log number using the LogDate function.
         > subtract the two numbers and check if it is greater than or equal 30 days to run the application and re-schedule the task again then
            create new log file with the current log number or if not greater than or Equal 30  just quite.



All what you have to do is set the variables in lines 6 to 9 and every thing supposed to work as expected ( at least for me :) )

Code: Select all

@Echo OFF

Rem This Batch Runs Every time Windows Starts and Check if 30 dayes was passed or not
Rem if passed it runs the application and re-schadual the application to run again every 30 dayes

SET "LogFile=%userprofile%\Desktop\30days.log"         %= Log File Location and name =%
SET "Application=%programfiles%\7-zip\7zFM.exe"         %= Application Path =%
SET "Days=30"                                  %= How many days must pass to run the application =%
SET "TaskName=TaskB"                            %= Task Name must be the same to overwrite the task =%

rem Get current Log Number
CALL :LogDate "Stamp"

rem In case it was the first time to run
If Not Exist "%LogFile%" (
   rem [Stamp] Variable came from the LogDate Function
   Echo %Stamp%>"%LogFile%"
   rem Add the task
   schtasks /create /tn "%TaskName%" /tr "%Application%" /sc daily /mo %Days% /ru "" /f >NUL
   Exit
   )

rem In case it wasn't the first time to run
IF Exist "%LogFile%" (
   rem Get the log number
   For /F "delims=" %%A In (' Type "%LogFile%" ') Do SET "LogNumber=%%A"
   rem Compare current Stamp {line 12} with the logfile log number
   SET /A check = Stamp - LogNumber
   SETLOCAL EnableDelayedExpansion
   Rem [ NOTE ] : It will run the exe and re-schdual the task if GREATER than OR EQUAL 30 days like 30 or 31
   IF "!check!" GEQ "%Days%" (
      Rem Re-set the Task
      schtasks /create /tn "%TaskName%" /tr "%Application%" /sc daily /mo %Days% /ru "" /f >NUL
      Rem Start the Application
      Start "" "%Application%"
      Rem Create New Log File
      Echo %Stamp%>"%LogFile%"
   )
)
Exit

Rem ===[ Log date function ]========================================================
:logDate <variable_Name>
rem The Time Format in my PC is as follow : Wed 04/10/2013  [DayName-Month-Day-Year]
rem Time logged in the log file is based on the above format,
rem if your system differant modify the function
SET "day=%date:~7,2%"
SET "month=%date:~4,2%"
SET "year=%date:~10,4%"
SET /A T1 = month * 30      %= Convert month to dayes by multiplying in 30 =%
SET /A number = T1 + day      %= Add the result to the dayes and log in the log file =%
SET "%~1=%number%"
GOTO :EOF


for now it work depending on this date format : Wed 04/10/2013 [DayName-Month-Day-Year]
i will try to make it work in general if it worked

The function work as the following:
it take the month and multiply in 30, then add the result to the days number, this is the number stored in the log file

Edited:
Replace The LogDate Function with this, it might be more general and not local setting limited

Code: Select all

:logDate <variable_Name>
For /F "tokens=1 delims=." %%A In (' WMIC OS GET LocalDateTime ') Do SET "LDT=%%A"
SET "day=%LDT:~6,2%"
SET "month=%LDT:~4,2%"
SET "year=%LDT:~0,4%"
SET /A T1 = month * 30      %= Convert month to dayes by multiplying in 30 =%
SET /A number = T1 + day      %= Add the result to the dayes and log in the log file =%
SET "%~1=%number%"
GOTO :EOF


Fixed the error in the function
Last edited by abc0502 on 09 Apr 2013 19:10, edited 2 times in total.

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: Could use some help with how to do batch code?

#27 Post by Squashman » 09 Apr 2013 18:25

batchfile wrote:
Squashman wrote:I also don't want to wait 10 minutes

You have a scheduled task that runs every 30 days and you cant wait 10 more minutes for it to run? Do you know how anal retentive that sounds?

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Could use some help with how to do batch code?

#28 Post by abc0502 » 09 Apr 2013 18:59

Updated my post!

BTW, any one experience any heavy in loading editing or posting on forum or it's just me :?

batchfile
Posts: 13
Joined: 09 Apr 2013 01:27

Re: Could use some help with how to do batch code?

#29 Post by batchfile » 09 Apr 2013 19:06

abc0502 wrote:Ok, try this, i hope that what you need :roll:

There will be no check.bat or other batch files, just one.
Put that batch in the start-up folder or in the registry, and when it runs it do the following:

Code: Select all

Check to see if a log file exist:
    [+] IF not that means it is the first time and it will create a log file with a number ( will explain that later ), then schedule the
         task to run after 30 days ( will not run the application, if you need it to say it ).
    [+] IF the file exist that means it was run before and will check the log file as following:
         > get the number from the log file.
         > get the current log number using the LogDate function.
         > subtract the two numbers and check if it is greater than or equal 30 days to run the application and re-schedule the task again then
            create new log file with the current log number or if not greater than or Equal 30  just quite.



All what you have to do is set the variables in lines 6 to 9 and every thing supposed to work as expected ( at least for me :) )

Code: Select all

@Echo OFF

Rem This Batch Runs Every time Windows Starts and Check if 30 dayes was passed or not
Rem if passed it runs the application and re-schadual the application to run again every 30 dayes

SET "LogFile=%userprofile%\Desktop\30days.log"         %= Log File Location and name =%
SET "Application=%programfiles%\7-zip\7zFM.exe"         %= Application Path =%
SET "Days=30"                                  %= How many days must pass to run the application =%
SET "TaskName=TaskB"                            %= Task Name must be the same to overwrite the task =%

rem Get current Log Number
CALL :LogDate "Stamp"

rem In case it was the first time to run
If Not Exist "%LogFile%" (
   rem [Stamp] Variable came from the LogDate Function
   Echo %Stamp%>"%LogFile%"
   rem Add the task
   schtasks /create /tn "%TaskName%" /tr "%Application%" /sc daily /mo %Days% /ru "" /f >NUL
   Exit
   )

rem In case it wasn't the first time to run
IF Exist "%LogFile%" (
   rem Get the log number
   For /F "delims=" %%A In (' Type "%LogFile%" ') Do SET "LogNumber=%%A"
   rem Compare current Stamp {line 12} with the logfile log number
   SET /A check = Stamp - LogNumber
   SETLOCAL EnableDelayedExpansion
   Rem [ NOTE ] : It will run the exe and re-schdual the task if GREATER than OR EQUAL 30 days like 30 or 31
   IF "!check!" GEQ "%Days%" (
      Rem Re-set the Task
      schtasks /create /tn "%TaskName%" /tr "%Application%" /sc daily /mo %Days% /ru "" /f >NUL
      Rem Start the Application
      Start "" "%Application%"
      Rem Create New Log File
      Echo %Stamp%>"%LogFile%"
   )
)
Exit

Rem ===[ Log date function ]========================================================
:logDate <variable_Name>
rem The Time Format in my PC is as follow : Wed 04/10/2013  [DayName-Month-Day-Year]
rem Time logged in the log file is based on the above format,
rem if your system differant modify the function
SET "day=%date:~7,2%"
SET "month=%date:~4,2%"
SET "year=%date:~10,4%"
SET /A T1 = month * 30      %= Convert month to dayes by multiplying in 30 =%
SET /A number = T1 + day      %= Add the result to the dayes and log in the log file =%
SET "%~1=%number%"
GOTO :EOF


for now it work depending on this date format : Wed 04/10/2013 [DayName-Month-Day-Year]
i will try to make it work in general if it worked

The function work as the following:
it take the month and multiply in 30, then add the result to the days number, this is the number stored in the log file

Edited:
Replace The LogDate Function with this, it might be more general and not local setting limited

Code: Select all

:logDate <variable_Name>
For /F "tokens=1 delims=." %%A In (' WMIC OS GET LocalDateTime ') Do SET "LDT=%%A"
SET "day=%date:~6,2%"
SET "month=%date:~4,2%"
SET "year=%date:~0,4%"
SET /A T1 = month * 30      %= Convert month to dayes by multiplying in 30 =%
SET /A number = T1 + day      %= Add the result to the dayes and log in the log file =%
SET "%~1=%number%"
GOTO :EOF



:shock: Wow

Thanks for initiating testing, will return with results or questions

Image

abc0502 wrote:Updated my post!

BTW, any one experience any heavy in loading editing or posting on forum or it's just me :?


Things are fine on this end 8)

Squashman wrote:
batchfile wrote:
Squashman wrote:I also don't want to wait 10 minutes

You have a scheduled task that runs every 30 days and you cant wait 10 more minutes for it to run? Do you know how anal retentive that sounds?


lol...I understand your perspective and can resonate with the humor intended but I think my desires of wanting a single .cmd file have been passed by of which I can appreciate in their being different angles to approach a challenge or coding

I really just like .cmd file even to the point of using .cmd files to create a .bat file and place in windows location hence again only one .bat file is needed

Thanks again SM
Last edited by batchfile on 09 Apr 2013 19:11, edited 1 time in total.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Could use some help with how to do batch code?

#30 Post by abc0502 » 09 Apr 2013 19:08

sorry the function i posted has error, i will update the post again.

Post Reply