Advertisement

There's no such thing as a stupid question, but they're the easiest to answer.
Login
Search

Advertisement

Software Development Software Development
Search Search
Search for:
Tech Support Guy > > >

Batch File For/If Loop issue.


(!)

MysticPixie's Avatar
MysticPixie MysticPixie is offline
Member with 102 posts.
THREAD STARTER
 
Join Date: May 2009
Experience: Advanced
05-May-2009, 02:04 PM #1
Question Batch File For/If Loop issue.
(Note: The client machines that will be running this batch file will all be WinXP, and my own machine has the 2k3 resource kit also, and much of this was written on Vista and verified on XP. I've been writing batch files in some manner or another for ~10 years).

Alright, so I like to think I'm good with batch, but inevitably I miss something really silly and end up scratching my head for days. I've asked a lot of people that I work with, and no one seems to have an answer aside from "Well, don't use batch use (insert scripting language that I don't know here)". While I'm working on learning other languages, I'm still a big fan of batch, and it's what I've used for years. Anyway, to my problem...

There is a specific application installed throughout our domain on random computers which needs to go away. The easiest way I can see to do this is to have a batch file called from the startup scripts that checks the machine for the files, and if it finds them, it kills them. Here's what I've got...

Code:
 
Dir /s /b %SYSTEMDRIVE%\ | Find /i "DWRCS.exe" > %SYSTEMDRIVE%\dwtoremove.txt
Dir /s /b %SYSTEMDRIVE%\ | Find /i "DNTUS26.exe" >> %SYSTEMDRIVE%\dwtoremove.txt
Dir /s /b %SYSTEMDRIVE%\ | Find /i "DWRCS.INI" >> %SYSTEMDRIVE%\dwtoremove.txt
Dir /s /b %SYSTEMDRIVE%\ | Find /i "DWRCK.DLL" >> %SYSTEMDRIVE%\dwtoremove.txt
Dir /s /b %SYSTEMDRIVE%\ | Find /i "DWRCSET.DLL" >> %SYSTEMDRIVE%\dwtoremove.txt
Dir /s /b %SYSTEMDRIVE%\ | Find /i "DWRCSHELL.DLL" >> %SYSTEMDRIVE%\dwtoremove.txt
Dir /s /b %SYSTEMDRIVE%\ | Find /i "DWRCST.EXE" >> %SYSTEMDRIVE%\dwtoremove.txt
 
:Loop
For /f %%i IN (%SYSTEMDRIVE%\dwtoremove.txt) DO (
Set DWRPATH="%%i"&& If /i %DWRPATH:~-14,13% EQU DWRCSHELL.DLL (
Del /f /q %DWRPATH%
) Else (
If /i %DWRPATH:~-11,10% EQU DWRCST.EXE (
Del /f /q %DWRPATH%
)
)
Now then, here's the various problems that I've run into.

If I put the IF loop outside of the For loop so that %%i is updated each time for use in the DWRPATH variable. When I do that, %%i never truly gets updated, even if I try to use an increment variable counter to know how many times I've been through the loops, because it thinks each execution of the For loop is the first execution (which logically it is).

I can't pass a wildcard to the If statement to try and match the file path, hence the need for the variable DWRPATH, and parsing only the last x characters of the string given by the data file for the compare statement.

With the If statement embedded WITHIN the For Loop, %%i never actually gets updated. Here's the kicker. If DWRPATH has a value BEFORE the loop begins (i.e. after i've run the batch file, but didn't clean up the variables, or just set the variable beforehand for testing) then the IF statements work fine (in that the variable is present, and gets compared). If DWRPATH does **NOT** have a value prior to the batch file being run, the If statement doesn't work at all. It doesn't like me trying to parse a variable that doesn't exist (13 was unexpected at this time.)

If I embed the If loop outside of the For loop sure the variable gets updated, but by the time the If Loop gets to it, it's the final line of the file and no good. Or, I goto the If loop from within the for loop (i.e. Goto Loop2), and the file just loops infinitely because the For loop only ever grabs the first line of the text file.

Also, I tried it with SetLocal EnableDelayedExtensions but the If statements choke on the ! in place of %.

I think I'm out of tricks at this point. Hoping someone more skilled in the ways of the almighty batch file might have some insight.

Thanks,

Misty
TheOutcaste's Avatar
Computer Specs
Member with 9,028 posts.
 
Join Date: Aug 2007
Location: Oregon, USA
Experience: Intermediate
05-May-2009, 10:31 PM #2
Welcome to TSG!
Quote:
Originally Posted by MysticPixie View Post
Also, I tried it with SetLocal EnableDelayedExtensions but the If statements choke on the ! in place of %.
That should be SetLocal EnableDelayedExpansion, not Extensions
And that should work just fine:
Code:
:Loop
SetLocal EnableDelayedExpansion
For /F %%i In (%SYSTEMDRIVE%\dwtoremove.txt) Do (
  Set DWRPATH="%%i"&& If /I !DWRPATH:~-14,13% EQU DWRCSHELL.DLL (
    Del /F /Q !DWRPATH!
    ) Else (
    If /i !DWRPATH:~-11,10! EQU DWRCST.EXE (
    Del /F /Q !DWRPATH!
    )
)
Really no need to use the DWRPATH variable though. You can use loop modifiers to extract just the file name to do the compare:
Code:
:Loop
For /F %%i In (%SYSTEMDRIVE%\dwtoremove.txt) Do (
  If /I %%nxi EQU DWRCSHELL.DLL (
    Del /F /Q %%i
    ) Else (
    If /I %%nxi EQU DWRCST.EXE (
      Del /F /Q %%i
    )
)
If the folders that contain the files to be removed contain spaces, the loop variable (or DWRPATH) will need to be quoted and you'll need to specify no delimiters in the For loop:
Code:
:Loop
 For /F "Delims=" %%i In (%SYSTEMDRIVE%\dwtoremove.txt) Do (
   If /I %%nxi EQU DWRCSHELL.DLL (
     Del /F /Q "%%i"
     ) Else (
     If /I %%~nxi EQU DWRCST.EXE (
       Del /F /Q "%%i"
     )
 )
The above only deletes two files, dwrcshell.dll and dwrcst.exe, so I don't see why you are checking for the other file names if you don't want to delete them. A full DIR of the drive will take sometime, so no need to repeat it for files you don't want to delete.
If you want to delete all of the files, you don't need the if statement, just a simple For loop:
Code:
:Loop
  For /F "Delims=" %%i In (%SYSTEMDRIVE%\dwtoremove.txt) Do Del /F /Q "%%i"
You should also check for the existence of the dwtoremove.txt file. If run on a system that doesn't have those files, dwtoremove.txt will never be created and the loop will fail with a file not found error. And creating a flag file after the files have been deleted would be a good idea. If present, no need to run the program again (unless it's been re-installed).
The Dir can be sped up a bit by specifying part of the file name. Search first for DWRC*.* and use Findstr to search the resulting file for the specific names, rather than doing a full Dir for each name. Then search a 2nd time for the DNTUS26.exe file.
So I would use this:
Code:
:: Check for flag file
If Exist %SYSTEMDRIVE%\dwrflag.txt Goto :EOF
:: Remove dwtoremove to get a clean start
If Exist %SYSTEMDRIVE%\dwtoremove.txt Del /F /Q %SYSTEMDRIVE%\dwtoremove.txt
:: Get files starting with DWRC into a temp file
>"%temp%\}DWRCheck{.txt" Dir /S /B %SYSTEMDRIVE%\DWRC*.*
:: Search for the DNTUS26.exe file and put its path into dwtoremove.txt
>%SYSTEMDRIVE%\dwtoremove.txt Dir /S /B %SYSTEMDRIVE%\DNTUS26.exe
:: Parse the temp file to extract the path to each specific file
>>%SYSTEMDRIVE%\dwtoremove.txt Findstr /I "DWRCS.EXE DWRCS.INI DWRCK.DLL DWRCSET.DLL DWRCSHELL.DLL DWRCST.EXE" "%temp%\}DWRCheck{.txt"
:: Delete the temp file
Del /F /Q "%temp%\}DWRCheck{.txt"
If dwtoremove.txt doesn't exist, none of the files were found
If NOT Exist %SYSTEMDRIVE%\dwtoremove.txt Goto SkipLoop
:: Now we delete each file in dwtoremove.txt
:Loop
For /F "Delims=" %%i In (%SYSTEMDRIVE%\dwtoremove.txt) Do @Echo Del /F /Q "%%i"
:: Remove the list of files
If Exist %SYSTEMDRIVE%\dwtoremove.txt Del /F /Q %SYSTEMDRIVE%\dwtoremove.txt
:SkipLoop
:: Create flag file showing the files have been removed
>%SYSTEMDRIVE%\dwrflag.txt Echo DWR has been removed
I've added the @Echo so this won't actually delete any files.
Use that to verify this will only delete the files you want to remove, then remove the @Echo. And for testing, comment out the last two lines, so the flag file won't be created, and the dwtoremove.txt file will be left so you can look at it.

HTH

Jerry

Last edited by TheOutcaste; 06-May-2009 at 02:16 PM.. Reason: Added Missing Tilde
MysticPixie's Avatar
MysticPixie MysticPixie is offline
Member with 102 posts.
THREAD STARTER
 
Join Date: May 2009
Experience: Advanced
06-May-2009, 08:27 AM #3
Quote:
That should be SetLocal EnableDelayedExpansion, not Extensions
Pretty sure I used the right one, I can't remember though. I grabbed it from the batch a-z reference on MS's site. I'll doublecheck it though. I've done so much mangling of this I could have easily sussed it up LOL.

Quote:
Really no need to use the DWRPATH variable though. You can use loop modifiers to extract just the file name to do the compare:

Code:
If /I %%nxi
I'm confused by the "%%nxi". Does that provide space for three variables being read in one at a time?

Quote:
If the folders that contain the files to be removed contain spaces, the loop variable (or DWRPATH) will need to be quoted and you'll need to specify no delimiters in the For loop:
That was the main reason for the DWRPATH variable being in quotes. I don't want this to break if the path contains spaces. That's also the reason for the :~-x,y pieces. Starts all the way at the right of the name, and skips one character (the quote) grabbing the rest of the name so that it works in the string comparison.

Quote:
so I don't see why you are checking for the other file names if you don't want to delete them. A full DIR of the drive will take sometime, so no need to repeat it for files you don't want to delete.
If you want to delete all of the files, you don't need the if statement, just a simple For loop:
The main thing was just to get the loop to work for 2 files. I can make it work just fine for 1 file, but making it work for 2 is the same as making it work for x. Once I get it working for 2 files, I can get the rest filled in. Some files have to be treated differently. 2 of the executables need to be executed with a special switch to remove the service, then deleted after that executes. The DLLs need to be unregistered before they are deleted. All of these can be handled just by doing a quick Set Flag = whatever, then check the flag later and if it shows the file was there and modified, then it's ready to be deleted and I can delete it. Some can just be deleted immediately.

Or I could just do a && after the initial part, and delete after.

Quote:
The Dir can be sped up a bit by specifying part of the file name. Search first for DWRC*.* and use Findstr to search the resulting file for the specific names, rather than doing a full Dir for each name. Then search a 2nd time for the DNTUS26.exe file.
Definitely a good idea. I actually can't wait to get to work to give these a shot. Thanks so much!
MysticPixie's Avatar
MysticPixie MysticPixie is offline
Member with 102 posts.
THREAD STARTER
 
Join Date: May 2009
Experience: Advanced
06-May-2009, 10:40 AM #4
Grrrr...

This one's a buggar alright. And I checked (one of the many versions of) my batch file, and it was expansion, not extention that I was using.

Something is up in my if statement though. you can parse specific characters of an environment variable using :~x,y (where if x is negative then it simply starts at the far right character of the variable, and parses y characters towards the front of the variable). However that functionality seems broken here for some reason.

You can test the functionality with:
Code:
Set TestVar=HelloWorld!
echo %TestVar:~-6,5%
echo %TestVar:~0,5%
Which will return:
Code:
World
Hello
The whole reason I'm doing that is so that I can parse just the end of the string to make sure that just the filename matches. I don't care what directory it's in (beyond needing to full path to make it go bye bye, unregister, kill service, etc.).

I try to write code that's portable and will work no matter where something is. I don't even like hardcoding the filenames in there, and would prefer to pass those in via an ini file, but for now this only has one purpose. Should we find it needs to be expanded in the future, I can tweak it to take command paramters (I have working code to grab data from an ini file somewhere)s. It's just a basic check for parameters, shift, parse parameters, then pull the data from the ini file it's pointed to.

But baby steps. First I have to get the code working. And so far no-go.

Interesting note, with this:
Code:
Setlocal EnableDelayedExpansion
 
Set DWRPATH=Test
 
For /F %%i IN (%SYSTEMDRIVE%\dwtoremove.txt) DO (
Set DWRPATH="%%i"&& If /I "!DWRPATH:~-14,13!"EQU DWRCSHELL.DLL (
ECHO "!DWRPATH!"
) Else (
If /i "!DWRPATH:~-11,10!"EQU DWRCST.EXE (
ECHO "!DWRPATH!"
)
)
I get this output:

Quote:
D:\>fortest.bat
D:\>Setlocal EnableDelayedExpansion
D:\>Set DWRPATH=Test
D:\>
D:\>
If the "Set DWRPATH=Test" is NOT there (i.e. commented out or deleted), I get this:

Quote:
D:\>fortest.bat
D:\>Setlocal EnableDelayedExpansion
D:\>D:\>
For some reason the drive letter prompt gets dropped on the same line empty. Is this a bracketing issue maybe? I've played with them a bit but it doesn't seem to like me very much when I play with them.
Squashman's Avatar
Trusted Advisor with 19,643 posts.
 
Join Date: Apr 2003
Location: 1265 Lombardi Ave
06-May-2009, 02:52 PM #5
Quote:
Originally Posted by MysticPixie View Post
I'm confused by the "%%nxi". Does that provide space for three variables being read in one at a time?
Read the Help for FOR loops.

Quote:
In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:

%~I - expands %I removing any surrounding quotes (")
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only
%~sI - expanded path contains short names only
%~aI - expands %I to file attributes of file
%~tI - expands %I to date/time of file
%~zI - expands %I to size of file
%~$PATH:I - searches the directories listed in the PATH
environment variable and expands %I to the
fully qualified name of the first one found.
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string

The modifiers can be combined to get compound results:

%~dpI - expands %I to a drive letter and path only
%~nxI - expands %I to a file name and extension only
%~fsI - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
environment variable for %I and expands to the
drive letter and path of the first one found.
%~ftzaI - expands %I to a DIR like output line

In the above examples %I and PATH can be replaced by other valid
values. The %~ syntax is terminated by a valid FOR variable name.
Picking upper case variable names like %I makes it more readable and
avoids confusion with the modifiers, which are not case sensitive.
TheOutcaste's Avatar
Computer Specs
Member with 9,028 posts.
 
Join Date: Aug 2007
Location: Oregon, USA
Experience: Intermediate
06-May-2009, 03:09 PM #6
Quote:
Originally Posted by MysticPixie View Post
I'm confused by the "%%nxi". Does that provide space for three variables being read in one at a time?
Opps, that should have been %%~nxi. The ~nx is a modifier, specifying the filename (n) and extension (x). Enter For /? in a command prompt. The modifiers are explained at the end.

EDIT: Or just read what Squashman posted as I was typing this

So %%~nxi will extract just the filename from the %%i variable. Does the same as using %var:~-X,Y% in a set statement to extract a string, but without needing to specify the length, or account for quotes
Quote:
Originally Posted by MysticPixie View Post
The main thing was just to get the loop to work for 2 files.
Gotcha. Once the file names are all in the dwtoremove file, seems a simple list if If statements would work.
To unregister then delete the dlls, this should work
Code:
If /I %~xi=dll (
 regsvr32 /u "%%~nxi"
 Del /F /Q "%%i"
)
Quote:
Originally Posted by MysticPixie View Post
Code:
Setlocal EnableDelayedExpansion
 
Set DWRPATH=Test
 
For /F %%i IN (%SYSTEMDRIVE%\dwtoremove.txt) DO (
Set DWRPATH="%%i"&& If /I "!DWRPATH:~-14,13!"EQU DWRCSHELL.DLL (
ECHO "!DWRPATH!"
) Else (
If /i "!DWRPATH:~-11,10!"EQU DWRCST.EXE (
ECHO "!DWRPATH!"
)
)
I get this output:
Quote:
D:\>fortest.bat
D:\>Setlocal EnableDelayedExpansion
D:\>Set DWRPATH=Test
D:\>
D:\>
If the "Set DWRPATH=Test" is NOT there (i.e. commented out or deleted), I get this:
Quote:
D:\>fortest.bat
D:\>Setlocal EnableDelayedExpansion
D:\>D:\>
You need one more closing parenthesis. The For loop doesn't have the closing parenthesis, so it's waiting for another command line. But the file ends instead, which leaves it on the same line, so you get the double prompt like that. I got that whether or not the Set DWRPATH=Test line is there or not, so not quite sure why you get that first result.
My sample dwtoremove.txt file has all the files in C:\Windows\System32; if the path is different, that might make a difference.
I suspect this is just a typo in the posted code, but there should be a space between the " and the EQU.
The If statements need to be quoted on both sides.
When !DWRPATH:~-14,13! is DWRCSHELL.DLL, your If statement is this:
If /i "DWRCSHELL.DLL" EQU DWRCSHELL.DLL
These will never be equal as the left side has quotes and the right does not.
Try this first, to verify the variable is getting set correctly. This will also show that %%~nxi will always get just the filename and extension
Code:
@Echo Off
Setlocal EnableDelayedExpansion
For /F %%i IN (%SYSTEMDRIVE%\dwtoremove.txt) DO (
Set DWRPATH="%%i"
Echo Loop Var is:%%i
ECHO DWRPATH is:!DWRPATH!
Echo Substring of DWRPATH is:!DWRPATH:~-14,13!
Echo Filename [~nxi] is:%%~nxi
)
Then try this:
Code:
@Echo Off
Setlocal EnableDelayedExpansion
For /F %%i IN (%SYSTEMDRIVE%\dwtoremove.txt) DO (
If /I "%%~nxi" EQU "DWRCSHELL.DLL" ECHO "%%i"
If /I "%%~nxi" EQU "DWRCST.EXE" ECHO "%%i"
)
The quotes aren't needed for these filenames since they don't have spaces, but can't hurt to include them so it will work if there are spaces.

HTH

Jerry
MysticPixie's Avatar
MysticPixie MysticPixie is offline
Member with 102 posts.
THREAD STARTER
 
Join Date: May 2009
Experience: Advanced
07-May-2009, 06:50 PM #7
doh. batch fail.
Well, thanks for all your help guys (and even for the RTFM comment, I really should have looked at the command help a bit closer one of the 500 times I looked at it).

Unfortunately this is one job batch just can't handle.

One of the processes that has to be killed, is done so via executing:

Code:
filename.exe -remove
I can't believe I didn't realize the absurdity of trying to do this with a batch file earlier. The instant the command processor sees "rem", poof! Commented out.

Time to go pick up some vbscript books I suppose.

Thanks again.
TheOutcaste's Avatar
Computer Specs
Member with 9,028 posts.
 
Join Date: Aug 2007
Location: Oregon, USA
Experience: Intermediate
07-May-2009, 11:14 PM #8
filename.exe -remove should work just fine.
The command processor won't see this as a remark. You can't have two commands on the same line without using an ampersand or pipe (&, &&, |, or ||). (*goto is one exception)
In this case filename.exe is the first command, so everything after the 1st space is sent to filename.exe as command line parameters.
If filename.exe it is not found, it will give an error, so if not on the path, that will need to be specified
Also, there is no space after the - or the M, so it would see -REMOVE, not REM or REMARK. Even if it did see it as a command, you'd get this error:
'-remove' is not recognized as an internal or external command, operable program or batch file.
Example
Set var=test REM Set the variable
will set var equal to test REM Set the variable
you'd have to use this to get REM recognized as a remark command:
Set var=test&REM Set the variable
For example, notepad -remove is executed just fine, just gives an error that it can't find the file named -remove.txt

The batch file will wait until the called program finishes, so if the Remove fails, the batch file may hang.
You might need to use start so it doesn't wait
start filename.exe -remove
then use some method to make sure the removal has succeeded, such as using SC and find/findstr to see if the service is still present.

Another thought, is there an uninstall icon in the start menu Program Group? If so, you can just execute the uninstaller from the batch file by using the command line from the shortcut. That might require user interaction though, but if it uses the msiexec.exe program to install/uninstall, you can just add the /quiet switch. From their website, the install file for the latest version (6.8.1.4) is a .MSI, so they do use msiexec.exe

Jerry

*Goto is an exception, as you can't have additional commands on the same line as goto. Labels can't contain spaces, so processing stops at the first space after the label, so you can type anything after the label and it will be ignored, so this is valid:
Goto label this stuff will be ignored by the command processor
MysticPixie's Avatar
MysticPixie MysticPixie is offline
Member with 102 posts.
THREAD STARTER
 
Join Date: May 2009
Experience: Advanced
08-May-2009, 02:26 AM #9
Yea I thought about that right after I made the post (about rem not being seen as the remark bit). I didn't actually test it before I did the post, i just looked at it, wondered why it got color coded like the rest of the comments, then had an "aw crap" moment.

And promptly rushed off to a meeting.

As for the msi bit. i wish it were that easy. unfortunately, I don't know if it's the version that we're using, or if it's because of it being installed a certain way, but there is no executable to simply call with a kill switch to nuke it.

Going to be running it through it's paces tomorrow. I thumped my machine with it, which only has a couple of the files, and the ones that i created just to test the parsing obviously aren't going to work as actual executables, so tomorrow i get to hunt for a machine to run it against.

Much thanks for your help. I really should write batch more often. I've lost my touch >_<

Those nifty "for" pieces? Epic. WAAAAAY easier than my little :~ parsing bit. More effective too given the circumstances.

So uh, I like, owe you a beer or something now right? hehe.
TheOutcaste's Avatar
Computer Specs
Member with 9,028 posts.
 
Join Date: Aug 2007
Location: Oregon, USA
Experience: Intermediate
08-May-2009, 02:47 AM #10
Quote:
Originally Posted by MysticPixie View Post
Going to be running it through it's paces tomorrow. I thumped my machine with it, which only has a couple of the files, and the ones that i created just to test the parsing obviously aren't going to work as actual executables, so tomorrow i get to hunt for a machine to run it against.
Good luck, hope it works OK
Quote:
Originally Posted by MysticPixie View Post
So uh, I like, owe you a beer or something now right? hehe.
If only that were possible. Boy, would we be in trouble then. Closest I've found is this:
Beer over IP.

I need several though, Always need to re-fill my system:


MysticPixie's Avatar
MysticPixie MysticPixie is offline
Member with 102 posts.
THREAD STARTER
 
Join Date: May 2009
Experience: Advanced
08-May-2009, 08:20 PM #11
Thank you everyone for the tips, and for pointing out my "duh!" moments.

The script worked like a charm minus a couple of things, but I think it's more likely something shoddy with the way a dll file was hooked/loaded more than anything else.

But, the machine I nuked, the application got nuked, and the service had to be reinstalled before someone could connect, and the script didn't bork something that would prevent someone from being able to reinstall the service, so all seems well. We'll see how the full deployment goes, but so far so good! Yay!

Incidentally, do you have ANY idea how complicated it is to get a computer to tell you what "Yesterday" was? Zomg!

Sad thing is I **HAD** to write a vbscript for that (thankfully there was a very nice technet piece that was easily modifiable to do exactly what I wanted it to do).

Still though, freakish. Especially if you **NEED** the month/day to be represented as 2 digits. Crazy.

So um, should I post the finished code (modified so that the hardcoded *shudder* filenames are easily recognizable) so that someone else can search & snag a bit easier than trying to frankenstein it together from the various code snippets (some of which contain mangled code and horrific typos)?

Actually, don't answer that, I just will.

Hopefully it's helpful to someone else. If not, well what do I care it's not **MY** bandwidth ^_^

Thanks again!

(Code repost to follow....eventually)
TheOutcaste's Avatar
Computer Specs
Member with 9,028 posts.
 
Join Date: Aug 2007
Location: Oregon, USA
Experience: Intermediate
09-May-2009, 03:31 AM #12
Glad to hear it went fairly well
Quote:
Originally Posted by MysticPixie View Post
Incidentally, do you have ANY idea how complicated it is to get a computer to tell you what "Yesterday" was? Zomg!
If you want it to be independent of Regional Settings it's quite complex. But if you happen to already have a collection of date subroutines it's not too hard.
Code:
:: This will Display todays date and yesterdays date including the Day of the week
@Echo Off
:: Set the next variable equal to TAB followed by a Space
:: If you copy this code, you will have to manually edit this line
Set _TabSpace=     
Call :_GetDate
Call :_DOW %_Fdate%
Set _Today=%_DayW%
Call :_Jdate %_Fdate:~0,4% %_Fdate:~4,2% %_Fdate:~6,2%
Set /A _Jdate-=1
Call :_GDate %_Jdate%
Call :_DOW %GDate:~0,4%%GDate:~5,2%%GDate:~8,2%
IF %_iDate%==0 (
  Echo Today is%_TabSpace%%_Today% %_FDate:~4,2%%_sDate%%_FDate:~6,2%%_sDate%%_FDate:~0,4%
  Echo Yesterday was%_TabSpace%%_DayW% %GDate:~5,2%%_sDate%%GDate:~8,2%%_sDate%%GDate:~0,4%
)
IF %_iDate%==1 (
  Echo Today is%_TabSpace%%_Today% %_FDate:~6,2%%_sDate%%_FDate:~4,2%%_sDate%%_FDate:~0,4%
  Echo Yesterday was%_TabSpace%%_DayW% %GDate:~8,2%%_sDate%%GDate:~5,2%%_sDate%%GDate:~0,4%
)
IF %_iDate%==2 (
  Echo Today is%_TabSpace%%_Today% %_FDate:~0,4%%_sDate%%_FDate:~4,2%%_sDate%%_FDate:~6,2%
  Echo Yesterday was%_TabSpace%%_DayW% %GDate:~0,4%%_sDate%%GDate:~5,2%%_sDate%%GDate:~8,2%
)
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::  Subroutines
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_JDate
:: Convert date to Julian
:: Arguments : YYYY MM DD
:: Returns   : Julian date in _JDate
:: Usage
::Call :JDate %_GYear% %_GMonth% %_GDay%
:: First strip leading zeroes; a logical error in this
:: routine was corrected with help from Alexander Shapiro
::Code taken from datediff.bat written by Rob van der Woude
::http://www.robvanderwoude.com
:: Modified to handle months and days witout leading zeros
:: By TheOutcaste http://forums.techguy.org
Set _JMM=%2
Set _JDD=%3
IF 1%_JMM% LSS 110 Set _JMM=%_JMM:~-1%
IF 1%_JDD% LSS 110 Set _JDD=%_JDD:~-1%
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
Set /A _JMonth1 = ( %_JMM% - 14 ) / 12
Set /A _JYear1  = %1 + 4800
Set /A _JDate  = 1461 * ( %_JYear1% + %_JMonth1% ) / 4 + 367 * ( %_JMM% - 2 -12 * %_JMonth1% ) / 12 - ( 3 * ( ( %_JYear1% + %_JMonth1% + 100 ) / 100 ) ) / 4 + %_JDD% - 32075
For %%A In (_JMonth1 _JYear1) Do Set %%A=
Goto:EOF 
:_GDate
:: Convert Julian date back to "normal" Gregorian date
:: Argument : Julian date
:: Returns  : YYYY MM DD in GDate
::
:: Call :Gdate %JDate%
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
::
Set /A P      = %1 + 68569
Set /A Q      = 4 * %P% / 146097
Set /A R      = %P% - ( 146097 * %Q% +3 ) / 4
Set /A S      = 4000 * ( %R% + 1 ) / 1461001
Set /A T      = %R% - 1461 * %S% / 4 + 31
Set /A U      = 80 * %T% / 2447
Set /A V      = %U% / 11
Set /A _GYear  = 100 * ( %Q% - 49 ) + %S% + %V%
Set /A _GMonth = %U% + 2 - 12 * %V%
Set /A _GDay   = %T% - 2447 * %U% / 80
:: Clean up the mess
For %%A In (P Q R S T U V) Do Set %%A=
:: Add leading zeroes
IF 1%_GMonth% LSS 20 Set _GMonth=0%_GMonth%
IF 1%_GDay%   LSS 20 Set _GDay=0%_GDay%
:: Return value
Set GDate=%_GYear% %_GMonth% %_GDay%
Goto:EOF
:_GetDate
:: This batch file will always display the same results,
:: independent of "International" settings.
:: This batch file uses REG.EXE from the NT Resource Kit
:: (already installed with WinXP and Vista)
:: to read the "International" settings from the registry.
:: Date is returned as yyyymmdd in variable _fdate
:: Modified by The Outcaste from SortDate Written by Rob van der Woude
:: http://www.robvanderwoude.com
:: If passed a parameter use that for the date
If [%1]==[] (Set _Date=%date%) Else Set _Date=%1
If "%_Date%A" LSS "A" (Set _NumTok=1-3) Else (Set _NumTok=2-4)
:: Delims= is a TAB followed by a Space in the next two lines
For /F "TOKENS=2* DELIMS=%_TabSpace%" %%A In ('REG QUERY "HKCU\Control Panel\International" /v iDate') Do Set _iDate=%%B
For /F "TOKENS=2* DELIMS=%_TabSpace%" %%A In ('REG QUERY "HKCU\Control Panel\International" /v sDate') Do Set _sDate=%%B
IF %_iDate%==0 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%D%%B%%C
IF %_iDate%==1 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%D%%C%%B
IF %_iDate%==2 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%B%%C%%D
Goto:EOF
:_DOW
:: Calculates the Day of the Week for any date in the Gregorian Calander
:: Arguments : YYYYMMDD
:: Returns   : US English 3 letter abbreviation for the Day of Week in _DayW
:: Usage
:: Call _DOW YYYYMMDD
:: Written by TheOutcaste http://www.forums.techguy.org
Setlocal DisableDelayedExpansion
Set _Date=%1
Set _MTable=A033614625035
Set _DofWeek=SunMonTueWedThuFriSat
Set _cn=%_Date:~0,2%
Set _yr=%_Date:~2,2%
Set _mn=%_Date:~4,2%
Set _dy=%_Date:~6,2%
If %_cn:~0,1%==0 Set _cn=%_cn:~-1%
If %_yr:~0,1%==0 Set _yr=%_yr:~-1%
If %_mn:~0,1%==0 Set _mn=%_mn:~-1%
If %_dy:~0,1%==0 Set _dy=%_dy:~-1%
Set /A _ly=!(%_Date:~0,4%%%4)*!!(%_Date:~0,4%%%100)+!(%_Date:~0,4%%%400)
If %_mn% GEQ 3 Set _ly=0
Call Set _m=%%_MTable:~%_mn%,1%%
Set /A _Day=((2*(3-%_cn%%%4)+%_yr%+(%_yr%/4)+_m+_dy)%%7-_ly)*3
Call Set _Day=%%_DofWeeK:~%_Day%,3%%
Endlocal&Set _DayW=%_Day%

Last edited by TheOutcaste; 09-May-2009 at 10:12 PM.. Reason: Fixed bug in jdate routine if called with single digit day/month
MysticPixie's Avatar
MysticPixie MysticPixie is offline
Member with 102 posts.
THREAD STARTER
 
Join Date: May 2009
Experience: Advanced
09-May-2009, 06:09 PM #13
Post For/If Final Code (Working)
So just in case this might help someone in the future, here is the final working code that this thread helped get together...

Code:


@Echo Off
Setlocal EnableDelayedExpansion

 
>>%SYSTEMDRIVE%\dwrflag.txt Echo Beginning DWRemove pass...

 
:: Check to see if dwremove.txt exists. If it does, delete it so that we get a fresh file mapping.

 
IfExist%SYSTEMDRIVE%\dwtoremove.txt Del /f /q %SYSTEMDRIVE%\dwtoremove.txt

 
>"%temp%\DWRCheck.txt"Dir /s /b %SYSTEMDRIVE%\DWRC*.*

 
>%SYSTEMDRIVE%\dwtoremove.txt Dir /s /b %SYSTEMDRIVE%\DNTUS26.exe

 

>>%SYSTEMDRIVE%\dwtoremove.txt Findstr /i "DWRCS.EXE DWRCS.INI DWRCK.DLL DWRCSET.DLL DWRCSHELL.DLL DWRCST.EXE""%temp%\DWRCheck.txt"

 
Del /f /q "%temp%\DWRCheck.txt"

 

If NOT Exist%SYSTEMDRIVE%\dwtoremove.txt Goto EOF

 
For /f "delims="%%i IN (%SYSTEMDRIVE%\dwtoremove.txt) DO (
If /i "%%~nxi"EQU"DWRCS.EXE" (
"%%i" -remove
Del /f /q "%%i"
)
If /i "%%~nxi"EQU"DNTUS26.EXE" (
"%%i" -remove
Del /f /q "%%i"
)
If /i "%%~nxi"EQU"DWRCSHELL.DLL" (
regsvr32 /s /u /i /n "%%i"
Del /f /q "%%i"
)
If /i "%%~nxi"EQU"DWRCK.DLL" (
regsvr32 /s /u /i /n "%%i"
Del /f /q "%%i"
)
If /i "%%nxi"EQU"DWRCSET.DLL" (
regsvr32 /s /u /i /n "%%i"
Del /f /q "%%i"
)
If /i "%%nxi"EQU"DWRCS.INI"Del /f /q "%%i"
If /i "%%~nxi"EQU"DWRCST.EXE"Del /f /q "%%i"
)
 

>>%SYSTEMDRIVE%\dwrflag.txt Echo DWRemove has been run on this machine on %DATE:~4%.
Goto EOF
 
:EOF
Echo Done.
Doh! Had to strip out all the comments (My comments tend to be longer than the actual code LOL). Post was too long. Hate to do it, but wanted to get the working code posted in case someone else might ever need to solve a similar problem.
MysticPixie's Avatar
MysticPixie MysticPixie is offline
Member with 102 posts.
THREAD STARTER
 
Join Date: May 2009
Experience: Advanced
09-May-2009, 06:20 PM #14
Date Stuffs
Quote:
If you want it to be independent of Regional Settings it's quite complex. But if you happen to already have a collection of date subroutines it's not too hard.
Holy crap that's a lot of code. Here's what I did:

Small vbscript that I snagged from a larger posting on technet and altered to suit my needs:

Code:
DateYesterday = Date - 1
strYear = Year(DateYesterday)
strMonth = Month(DateYesterday)
IfLen(strMonth) = 1 Then
   strMonth = "0" & strMonth
End If
strDay = Day(DateYesterday)
IfLen(strDay) = 1 Then
   strDay = "0" & strDay
End If
strYesterday = strMonth & strDay & strYear
WScript.Echo strYesterday
My batch script looks like this:

Code:
Setlocal EnableDelayedExpansion
 

For /f %%i IN ('cscript //nologo %~dp0Date.vbs') DO Set ydate=%%i
 
For /f "delims="%%i IN (%~dp0Settings.ini) DO Set LogPath="%%i"
 
Set Today=%DATE:~4%
Set Month=%Today:~0,2%
Set Day=%Today:~3,2%
Set Year=%Today:~6,4%
Set YDay=%ydate:~2,2%
Set YMonth=%ydate:~0,2%
Set YYear=%ydate:~4,4%
Set YYear2=%YYear:~-2,4%
 
If%YMONTH%EQU 01 (
Set WMonth=Jan
) Else (
If%YMONTH%EQU 02 (
Set WMonth=Feb
) Else (
If%YMONTH%EQU 03 (
Set WMonth=Mar
) Else (
If%YMONTH%EQU 04 (
Set WMonth=Apr
) Else (
If%YMONTH%EQU 05 (
Set WMonth=May
) Else (
If%YMONTH%EQU 06 (
Set WMonth=Jun
) Else (
If%YMONTH%EQU 07 (
Set WMonth=Jul
) Else (
If%YMONTH%EQU 08 (
Set WMonth=Aug
) Else (
If%YMONTH%EQU 09 (
Set WMonth=Sep
) Else (
If%YMONTH%EQU 10 (
Set WMonth=Oct
) Else (
If%YMONTH%EQU 11 (
Set WMonth=Nov
) Else (
If%YMONTH%EQU 12 (
Set WMonth=Dec
))))))))))))
 
Set LongDate=%YDay%%WMonth%%YYear%
I'm still working on the rest of this thing. I have to generate an ftp script to upload a log file and to keep from having to hard-code paths into the ftp script (which would drive me completely buggo) I have to generate the ftp script when this runs putting variables into the ftp script (since I can't do it directly once ftp has been started). This whole thing is to simply grab yesterday's log file of an application, zip it (since it's like 2.5GB usually), and ftp it to the log-store.

I'm going to use an ftp script that uses directories to store the log file based on the date, to make it easy for us to locate a specific file.

Fun stuff.
TheOutcaste's Avatar
Computer Specs
Member with 9,028 posts.
 
Join Date: Aug 2007
Location: Oregon, USA
Experience: Intermediate
09-May-2009, 10:09 PM #15
VBScript does have a lot of built-in functions to handle strings and dates that make it far easier to manipulate those kind of things than in a batch file. You can get the year, day, and month regardless of the regional settings.


This might be a bit easier to get the Month abbreviation from the month number rather than using all the If statements:
Code:
Set strMonths=JanFebMarAprMayJunJulAugSepOctNovDec
:: Remove leading zero if present
If 1%Month% LSS 110 Set Month=%Month:~-1%
Set /A Month=(Month-1)*3
Call Set WMonth=%%Month:~%Month%,3%%
Using the nested Ifs lets low month numbers skip the following Ifs, but processing the Else command for the higher months might add more time than you save in the early months. With todays systems, I don't think you'd see a measurable speed difference between using the nested Ifs vs this:
Code:
If %YMONTH% EQU 01 Set WMonth=Jan
If %YMONTH% EQU 02 Set WMonth=Feb
If %YMONTH% EQU 03 Set WMonth=Mar
If %YMONTH% EQU 04 Set WMonth=Apr
If %YMONTH% EQU 05 Set WMonth=May
If %YMONTH% EQU 06 Set WMonth=Jun
If %YMONTH% EQU 07 Set WMonth=Jul
If %YMONTH% EQU 08 Set WMonth=Aug
If %YMONTH% EQU 09 Set WMonth=Sep
If %YMONTH% EQU 10 Set WMonth=Oct
If %YMONTH% EQU 11 Set WMonth=Nov
If %YMONTH% EQU 12 Set WMonth=Dec
You could also use a &Goto Label to skip the rest of the Ifs

Last edited by TheOutcaste; 09-May-2009 at 10:33 PM..
As Seen On

BBC, Reader's Digest, PC Magazine, Today Show, Money Magazine
WELCOME TO TECH SUPPORT GUY!

Are you looking for the solution to your computer problem? Join our site today to ask your question. This site is completely free -- paid for by advertisers and donations.

If you're not already familiar with forums, watch our Welcome Guide to get started.


Tags
batch, forif, loop

(clock)
THIS THREAD HAS EXPIRED.
Are you having the same problem? We have volunteers ready to answer your question, but first you'll have to join for free. Need help getting started? Check out our Welcome Guide.

Search Tech Support Guy

Find the solution to your
computer problem!




Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools


WELCOME
You Are Using: Server ID
Trusted Website Back to the Top ↑