Quote:
Originally Posted by scrfix 1. The maker does not change where they store the bat file. If they decide to store it in the program files directory, this would be disasterous.
2. If we are compiling utilizing that compiler. Other comilers store the bat directly in the temp directory without a folder and that would be disasterous as well to delete all of the files and directories before the temp directory. |
I tested using this bat to exe compiler, version 1.5.0.0:
Quote:
Originally Posted by Squashman |
Once the file is compiled, #1 and #2 won't be an issue. If you recompile using a different version, or a different complier, then you'd definitely need to re-test for both those situations. Good idea to check though. A year from now you may make a minor addition and forget that you're using a different version/compiler.
The first version using the
For /R %temp% would be a better choice in this case. That
For loop will delete all subfolders in the %temp% directory except for the one containing the batch file, if it exists. Doesn't matter if the batch file is in the temp tree, or someplace else, and it forces the comparison of the paths to use the short names, so no issues if a different compiler/newer version calls the batch file using long names. (more on this below)
You
would need to check before running the Del command. I left out the CD %temp% (or PushD %temp%), but the Del command assumes that the batch file and any included files are not in %temp%. If you include other files, and they are extracted into the %temp% folder rather than to a subfolder of %temp%, you'd need to check for and exclude all of them as well.
The 2nd example assumes the batch file is in a subfolder of %temp% and that the subfolder is not a long name, so it would need some modification as well to be more universal.
Quote:
Originally Posted by scrfix In one compiler, there is an option to change working directories however it doesn't work. |
In Kodak's compiler (the one linked above) the Working Directory option does work. It's not explained very well though.
- Current Directory means the current directory will be set to the directory from which the compiled exe file is run.
Any included files are copied to the same folder as the exe file when it is run. - Temporary Directory will use the Temp folder (HHHH.tmp) that the compiled batch file is extracted into.
Any included files will be extracted to that Temp folder as well.
The Submit current directory option will pass the Current Directory as defined above to the batch file on the command line as a quoted string. This will let you use %1 to refer to the folder that contains the compiled exe file.
You can test with this:
Code:
@Echo Current Directory=%CD%
@Echo Parameters=%1
Pause
There are two ways to refer to a path, using long names or using short names. They are equivalent, but they are not equal.
Example, on XP, my temp folder long name is:
C:\Documents and Settings\TheOutcaste\Local Settings\temp
%temp% expands using the short names to this:
C:\DOCUME~1\THEOUT~1\LOCALS~1\temp
Same path, but an If statement will not see those as equal as they are compared as strings.
On Vista it's
C:\Users\TheOutcaste\AppData\Local\Temp
C:\Users\THEOUT~1\AppData\Local\Temp
If your user name is less than 8 characters long, the long and short names will be the same.
The difficulty arises due to the fact that how %CD% is expanded depends on how you switched to the current directory. This is easiest to see on XP as the long and short names for the normal Temp folder will always be different.
Open a command prompt and type the following (using your username of course) and you'll see the difference:
Code:
CD "C:\Documents and Settings\TheOutcaste\Local Settings\temp"
Echo %CD%
CD %temp%
Echo %CD%
This also assumes that %temp% always expands using short names, which seems to be the case for Win2K-Vista. Haven't tested on Win7 yet. I do have a vague memory of having to use quotes around %temp% because of the space in Documents and Settings, but I may be thinking of one of the other variables. All the rest use the long name format
%0 is the name of the batch file
as called. So if called using short names, %dp0 will be the short name version. If called using long name, it will be long. The case
should match, but best to use the /I switch just in case.
Short names can be forced using the ~s modifier. See the last section in For /? and Call /? for info on the modifiers.
Quote:
Originally Posted by scrfix So if I understand this correctly. PushD %~dp0 (Change the directory to the current working directory where the batch is being run from.]) Set _batpath=%CD% (Set the variable _batpath equal to the current directory) cd .. (Go up one level) Del /F /Q *.* (Silently delete all of the files in that directory however do not touch sub directory files) For /F "Delims=" %%I In ('dir /AD /B') Do If /I NOT "%_batpath%"=="%%~fI" RD /Q /S "%%I" (Run a For Loop, Look for the delimiters ?? in the directory only listings with names only and store each one in the variable %%I then verify that the directory is not equal to the _batpath variable case insensitive [not sure what the ~f in %%~fI does] and if it is not equal to that, then run the command to remove the directory silently.) popD (This changes directory again as I understand it however without a directory following it when I enter it into a command line all it returns is the same directory)
Do I have that correct? |
Pretty much.
PushD and
PopD work together.
PushD saves the current directory on a stack, then does a
CD /D to the specified directory.
PopD pops the saved directory off the stack, and does a
CD /D to the saved directory. This way you don't have to save the current directory in a variable to restore it.
PopD will do nothing if there is nothing on the stack. If you are already in the "popped" directory it will seem to do nothing as well.
PushD %CD% doesn't change the current directory, but it does save it onto the stack, which can be useful.
This line should really be
PushD %~dps0. This will force it to use the short name version, just in case the compiler calls the file using the long name format. Not likely, but best to eliminate the possibility. This will allow you to compare %CD% to %temp%, as %CD% will use the short name format.
The For loop:
For /F "Delims=" means use no delimiters instead of the default delimiters of tab and space. This means the loop variable will be set to the entire line. Same result as using
"tokens=*" dir /AD /B lists directory names only, not including the path. Does not list files.
"%%~fI" The
~f expands to the fully qualified name. Equivalent to using
~dpnx. The output of this Dir command doesn't include the drive or path, just the name (and extension if any), so the
~f will add the current drive and path to the directory name.
One thing to remember when using modifiers with a loop variable, or with batch parameters
other than %0, is that they parse the content of the variable to extract drive, path, name, and extension. The drive, path, filename, file extension don't have to actually exist. You can make up a string for a non-existent drive, path, file name and extension, and the modifiers will extract the pieces as if it actually existed. The drive letter doesn't even have to be a letter. Any single character in the correct location will be seen as the drive letter.
The trick here is that if there are parts that are not included in the variable (in this case no drive or path, just a name and (maybe) an extension), it will substitute the
current path info. This is expanded using the same format as %CD%, so should match the Drive and Path in the _batfile variable.
Rather than switching to the directory that contains the batch file, then verifying if it's the temp directory, just switch to the temp directory, and check if the file is there. This avoids the issue of the compiler extracting it into Program Files or Windows
So to clear the Temp folder we have 3 possibilities:
- Extracted batch is in a subfolder under %temp%, along with all included files.
Delete all files in %temp%, and all subfolders except the one containing the batch file - Extracted batch and included files are in %temp%
Delete all subfolders, then delete all files in %temp% except the batch file and the included files.
You can include a list of files, or exclude extensions (.bat, .cmd, .exe). Excluding extensions may exclude many files other than the ones you've included though. - Extracted batch and included files are not in Temp.
Same process can be used as in #1, as the subfolder isn't there to be excluded
Code:
PushD %temp%
:: Delete all subfolders in temp except the one containing the batch file, if it exists.
For /R "%temp%" %%I In (.) Do If /I Not "%temp%\."=="%%I" If /I Not "%%~sI\"=="%~dps0" RD /Q /S "%%I"
:: Check if batch file is in the temp folder. If not, delete all files
If Not %~dps0==%temp% Del /F /Q *.*&Goto _tempcleared
:: batch and included files are in the temp folder
:: If a filelist wasn't included, create one to exclude the batch file.
If not exist "%~n0Filelist.txt" (
>"%~n0Filelist.txt" Echo %~nx0
>>"%~n0Filelist.txt" Echo %~n0Filelist.txt
)
For /F "Delims=" %%I In ('dir /A-D /B ^|findstr /I /V /G:"%~n0Filelist.txt"') Do Del "%%I"
:_tempcleared
PopD
This requires that you include a list of all included files in a file named
<filename>FileList.txt, where
<filename> is the name portion of the batch file, i.e., MyApp.cmd would include MyAppFileList.txt. Files are listed one per line, unquoted.
Breaking down the For loop into multiple lines:
Code:
For /R "%temp%" %%I In (.) Do (
If /I Not "%temp%\."=="%%I" (
If /I Not "%%~sI\"=="%~dps0" RD /Q /S "%%I"
)
)
This returns all the folder names starting at %temp%. It tacks on a
\. to each one, so we have to add that to the %temp% variable in the first If, which excludes the root directory (%temp%)
The next If compares the short name of the folder to the short name of the path to the batch file. If not equal, it deletes the folder. Using the ~s modifier removes the trailing
\.. This is because of the way the variable is parsed, so we have to add a \ to match the batch file path, which includes a trailing slash.
Jerry