This question is related to Test IF file exist, ELSE xcopy these two files.
Background: On occasion I choose to run aGallery-dl.bat
in a given folder (just one in each of 100's of folders). It first deletes Folder.jpg
then renames Folder2.jpg
to Folder.jpg
. This has the effect of a red X being replaced by a yellow ! when viewing the folder with parent folder selected in File Explorer. Secondly, it calls gallery-dl.exe
. I use going from red X to yellow ! to let me know I've run aGallery-dl.bat
at least once. If aGallery-dl.bat
completes successfully, it finally deletes the Folder.jpg
(currently yellow !), and now the representative contents of the folder (usually DeviantArt .jpg's) are visible. All is well.
rem @echo off
del .\Folder.jpg
ren .\Folder2.jpg Folder.jpg
FOR /F %%i IN ('cd') DO set FOLDER=%%~nxi
"C:\Program Files (x86)\gallery-dl\gallery-dl.exe" -d "U:\11Web\gallery-dl" --download-archive ".\aGDB.sqlite3" "https://www.deviantart.com/"%FOLDER%"/gallery/all"
del .\Folder.jpg
Problem: Restating, Gallery-dl.bat
is in each of 100's of folders. On occasion, I run one of these from within it's local folder. Line 5, if the call to the web site is successful, gallery-dl.exe
creates zzzGDB.sqlite3
within the local folder.
In the previous code, when aGallery-dl.bat
completed, it would just delete the Folder.jpg
. This assumes the call to the web page was successful. On rare occasion, the call to the web page will fail for any number of reasons, though at close (due to that final del .\Folder.jpg
), it will still delete folder.jpg
.
If zzzGDB.sqlite3
was not created/not present, I need the Folder.jpg
(yellow !) to remain.
So, in the below code (line 6, now blank), I've lopped off the final del .\Folder.jpg
and am trying to plug-in the provided code beginning at line 7, inserting a test for zzzGDB.sqlite
. If found, del .\Folder.jpg
. If not found, no action is taken against folder.jpg
(it remains).
(The rem
statement at the very bottom is just acting as a placeholder for my own knowledge.)
rem @echo off
del .\Folder.jpg
ren .\Folder2.jpg Folder.jpg
FOR /F %%i IN ('cd') DO set FOLDER=%%~nxi
"C:\Program Files (x86)\gallery-dl\gallery-dl.exe" -d "U:\11Web\gallery-dl" --download-archive ".\zzzGDB.sqlite3" "https://www.deviantart.com/"%FOLDER%"/gallery/all"
setlocal EnableExtensions DisableDelayedExpansion
for /D %%I in ("U:\11Web\gallery-dl\deviantart\*") do (
if exist "%%I\zzzGDB.sqlite3" (
del "%%I\Folder.jpg"
)
rem
)
endlocal
Note: Currently, the modified code goes back through every single folder within U:\11Web\gallery-dl\deviantart\*
. This action should be reserved only to the local folder. I'm guessing the below is the issue.
for /D %%I in ("U:\11Web\gallery-dl\deviantart\*")
I don't know how to remove it and still implement everything after do
?
do (
if exist ".\zzzGDB.sqlite3" (
del ".\Folder.jpg"
)
rem
)
I suggest to use following lines for aGallery-dl.bat
.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0" || exit /B
move /Y "Folder2.jpg" "Folder.jpg"
for %%I in (.) do set "FOLDER=%%~nxI"
"%ProgramFiles(x86)%\gallery-dl\gallery-dl.exe" -d "U:\11Web\gallery-dl" --download-archive "%~dp0zzzGDB.sqlite3" "https://www.deviantart.com/%FOLDER%/gallery/all"
if not errorlevel 1 if exist "zzzGDB.sqlite3" del "Folder.jpg"
popd
endlocal
The first two lines define the execution environment for the batch file.
The third line with command PUSHD pushes the current directory path on stack and sets the directory of the executed batch file as current directory. This works even on batch file being stored on a network resource accessed using a UNC path, except there is a network problem on execution of that command line.
The command exit /B
is executed in case of an error to immediately exit processing of the batch file on batch file directory could not be set as current directory. The Windows command processor runs implicitly the command ENDLOCAL in this case.
See Single line with multiple commands using Windows batch file for an explanation of operator ||
which results in conditionally executing exit /B
only if pushd
exited with a non-zero exit code indicating an error.
The fourth command line with MOVE does not really move the data of file Folder2.jpg
to file with name Folder.jpg
. In real it just updates the file system in this case as done also by the two commands del .\Folder.jpg
and ren .\Folder2.jpg Folder.jpg
in your batch file. This is just a very little bit faster method to replace one file by another file with the advantage that Folder.jpg
must not exist at all for success without displaying an error message as done by command DEL on file Folder.jpg
not existing.
The FOR command line determines the name of the current folder without path and assigns it to environment variable FOLDER
. This is a much faster and safer solution then using the command line:
FOR /F %%i IN ('cd') DO set FOLDER=%%~nxi
The command line above results in starting in background one more command process with %ComSpec% /c
and the command line between '
appended as additional arguments. So there is executed in background with Windows installed to C:\Windows
:
C:\Windows\System32\cmd.exe /c cd
The started cmd.exe
executes internal command cd
which outputs the full qualified folder name of current directory to handle STDOUT of background command process. This output is captured by cmd.exe
processing the batch file and is processed by for
after started cmd.exe
closed itself after finishing execution of command CD.
The command FOR would split up the folder path into substrings (tokens) using normal space and horizontal tab as string delimiters, would look next if the first space/tab delimited string starts with a semicolon in which case the captured line would be ignored for further processing, and would assign otherwise just the first space/tab delimited string to loop variable i
. So if the full qualified folder name of current directory would contain a space, this command line would fail to determine the folder name of current directory without path.
There is the dynamic variable CD
of which value can be referenced with %CD%
. The value is the full qualified folder name of current directory not ending with a backslash, except the root directory of a drive is the current directory. That would be identical to %~dp0
for batch file aGallery-dl.bat
with the difference that %~dp0
expands to full qualified name of batch file folder always with a backslash at end.
However, neither dynamic variable CD
nor %~dp0
nor execution of command CD in a separate command process in background are really useful to get name of current directory (= batch file directory) without path. The best method is using:
for %%I in (.) do set "FOLDER=%%~nxI"
This simple FOR does nothing else than getting name of current folder without path with a very fast executed file system query and assigning it to environment variable FOLDER
.
Note: for %%I in ("%~dp0.") do set "FOLDER=%%~nxI"
could be also used to get folder name without path of folder containing currently executed batch file if the current directory would not be the batch file directory.
The sixth command line executes gallery-dl.exe
with various parameters (arguments).
Please note that "https://www.deviantart.com/"%FOLDER%"/gallery/all"
is in real an invalid argument string. It is not valid to have "
inside a URL. The character "
is never valid inside an argument string which references a file or folder. This syntax error is detected and automatically fixed which is the reason why the command line in your batch file works at all. The correct argument string is "https://www.deviantart.com/%FOLDER%/gallery/all"
with one "
at beginning and one "
at end and no double quote inside the argument string enclosed in double quotes.
There is standard for console applications to exit with value 0
on success and a greater value like 1
on an error. I don't know if this is true also for gallery-dl.exe
, but I assume that with the command line:
if not errorlevel 1 if exist "zzzGDB.sqlite3" del "Folder.jpg"
if not errorlevel 1
checks if exit code of gallery-dl.exe
assigned to dynamic variable errorlevel
is NOT greater or equal 1
which means less than 1
which means equal 0
(on executable never exiting with a negative value which is not recommended to do by a program on any operating system) which means no error occurred during execution of gallery-dl.exe
. Please read the documentation of gallery-dl.exe
regarding to exit codes of this program or find it out with several executions in a command prompt window and using echo Exit code is: %errorlevel%
after each execution of gallery-dl.exe
with success or an error (like a wrong URL).
That condition should be already enough. But there is used one more condition to check for existence of the file zzzGDB.sqlite3
in current directory only before deleting the file Folder.jpg
in the current directory which is the batch file directory.
Please read issue 2 in this answer for the reason writing in batch file
if not errorlevel 1 if exist "zzzGDB.sqlite3" del "Folder.jpg"
instead of
if not errorlevel 1 (
if exist "zzzGDB.sqlite3" (
del "Folder.jpg"
)
)
The code above works also, but requires more CPU cycles for being processed by Windows command processor than the single line with two IF commands and one DEL command on one command line.
The last but one line pops the full qualified folder name of initial current directory from stack and sets it again as current directory and the last line restores initial execution environment on starting the batch file.
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
call /?
... explains %~dp0
... drive and path of argument 0 ... full batch file path.del /?
echo /?
endlocal /?
exit /?
for /?
move /?
popd /?
pushd /?
set /?
setlocal /?