There could be used following batch file on the server executed with its UNC path:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
cls
:DirectoryPrompt
set "WorkingDirectory=."
echo(
echo Please enter the working directory location.
echo(
echo The default on pressing just RETURN or ENTER is the directory:
echo(
cd
echo(
set /p "WorkingDirectory=Directory: "
set "WorkingDirectory=%WorkingDirectory:"=%"
if not defined WorkingDirectory goto DirectoryPrompt
for %%I in ("%WorkingDirectory%") do if exist "%%~fI\" (
set "WorkingDirectory=%%~fI"
) else (
echo ERROR: There is no directory:
echo(
echo %%~fI
goto DirectoryPrompt
)
set "LastName="
set "LastVersion=-1"
set "ListFile=%WorkingDirectory%\mylist.txt"
( for /F "eol=| delims=" %%I in ('dir "%WorkingDirectory%\*.drw.*" /A-D-L /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /R "\.drw\.[0123456789][0123456789]*$"') do (
set "CurrentName=%%~nI"
set "CurrentVersion=%%~xI"
setlocal EnableDelayedExpansion
if /I "!LastName!" == "!CurrentName!" (
if !CurrentVersion:~1! GTR !LastVersion:~1! (
endlocal
set "LastVersion=%%~xI"
) else endlocal
) else (
if defined LastName echo !LastName!!LastVersion!
endlocal
set "LastName=%%~nI"
set "LastVersion=%%~xI"
)
)
if defined LastName (
setlocal EnableDelayedExpansion
echo !LastName!!LastVersion!
endlocal
)
)>"%ListFile%"
if not defined LastName del "%ListFile%"
start "Trail generator" /D "%~dp0" "%~dp0trail_gen.exe"
endlocal
There is first defined completely the required execution environment with the first two command lines for
- turning off command echo mode,
- enabling command extensions,
- disabling delayed variable expansion.
Next is cleared the console window once on start of the batch file execution. That is useful on cmd.exe
outputs the information that it changed the current working directory on user executed the batch file using its UNC path with a double click in Windows File Explorer or another file management application. See my answer on CMD does not support UNC paths as current directories for more details.
The current directory on execution of a batch file can be always any directory because of the process starting cmd.exe
for processing a batch file defines on call of the Windows kernel library function CreateProcess with parameter lpCurrentDirectory
which directory should be the current working directory for cmd.exe
. The Windows File Explorer explorer.exe
passes usually the batch file directory path to CreateProcess
. But the Windows Command Processor changes itself the current working directory to the Windows directory (%SystemRoot%
) on UNC path is used by a user to run the batch file. Run as administrator causes often also a change of the current working directory to the Windows system directory (%SystemRoot%\System32
) before cmd.exe
is started at all. And last but not least a user could execute the batch file from within a command prompt window using its fully qualified file name with current working directory being the directory defined by the user.
The first block is for prompting the user on which directory the batch file should search for *.drw.*
files. There is first defined the environment variable WorkingDirectory
with .
to define the current directory as default. See the Microsoft documentation about Naming Files, Paths, and Namespaces for more details about the relative path .
.
The user is informed about what is expected to be entered by the user. The user can press key RETURN or ENTER to use the current directory as output into the console window using command CD without any arguments.
The DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ explains why echo(
is used to output an empty line which is the only syntax working always for the output of an empty line and not causing any file system access.
The user can drag and drop a directory, for example, from Windows File Explorer into the console window to input the directory path. The user can enter the directory also using a relative path.
The batch file then removes all "
from the user input string to process the string safely and secure further, see How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
The environment variable WorkingDirectory
is not defined anymore if the user entered by mistake (or intentionally) just "
in which case the user is prompted once again for the directory.
The batch file next gets the absolute path from the user input directory and verifies if the resulting string is indeed an existing directory. There must be always considered on letting a user enter a directory path string that the user made a typing mistake. The user is informed about the not existing directory and is prompted once again for the directory on a failure.
The environment variable LastName
is explicitly undefined in the current environment while the environment variable LastNumber
is explicitly defined with the negative number -1
.
ATTENTION 1:
Important is the definition of the environment variable ListFile
. In the code above the file names are written into a file with name mylist.txt
in the directory entered by the user. If that is a good fully qualified file name for the list file cannot be answered with the provided information. If the directory could be write-protected for the user, it is not good to use the variable definition as is.
Other possibilities are:
- Batch file directory with fixed file name:
set "ListFile=%~dp0mylist.txt"
That could be better if it is guaranteed that the user has always write access to this directory. It could be no good choice to use that list file name definition if multiple users could run the batch file at the same time.
- Batch file directory with variable file name:
set "ListFile=%~dp0%COMPUTERNAME%_%USERNAME%.txt"
The list file is created in this case also in the batch file directory with a file name consisting of the computer name and the user account name making it possible that multiple users run the batch file at the same time as long as the batch file is not run multiple times by the same user on same computer at the same time.
- User's temporary files directory with fixed name:
set "ListFile=%TEMP%\%~n0.txt"
The list file is created in the user's temporary files directory which is not write-protected with name of the batch file with file extension .txt
.
There are even more possibilities. What is best depends on further usage of the created text file.
The absolute working directory path could contain one or more exclamation marks as well as there could be files in this directory with usual names like ;Development & Test(!) 100%.drw.1
and ;Development & Test(!) 100%.drw.2
. The FOR loop itself and most of the commands inside the FOR loop are executed therefore with disabled delayed variable expansion as otherwise cmd
would interpret !
in working directory path of file names as beginning/end of a delayed expanded variable reference which would result in a not correct working batch file in this definitely not typical use cases.
There is executed in background one more command process with %ComSpec%
and option /c
and the command line defined with '
. So, there is executed in background with Windows installed into C:\Windows
and C:\Temp
being the working directory as entered by the user:
C:\Windows\System32\cmd.exe /c dir "C:\Temp\*.drw.*" /A-D-L /B /ON 2>nul | C:\Windows\System32\findstr.exe /I /R "\.drw\.[0123456789][0123456789]*$"
The command DIR searches in the user defined directory C:\Temp
for
- just files because of option
/A-D-L
(attribute not directory and not link)
- matching the wildcard pattern
*.drw.*
and
- outputs just the file names in bare format because of option
/B
without path
- ordered alphabetically by name because of option
/ON
.
This list of file names is passed as input to FINDSTR which searches with a case-insensitive regular expression for files ending with .drw.
and a number with one or more digits to filter out all *.drw.*
files not having a number after .drw.
in file name.
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul
and |
. The redirection operators >
and |
must be escaped with caret character ^
on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line with using a separate command process started in background.
FOR with option /F
captures the output written to handle STDOUT of background command process and processes it after started cmd.exe
closed itself.
There are always ignored empty lines by FOR which do not occur at all in this case.
FOR would split up each capture lines into substrings using normal space and horizontal tab as string delimiters and would assign only the first space/tab separated string to the specified loop variable I
. That string splitting behavior is not wanted here because of the file names could contain one or more spaces. The option delims=
at end of the options string defines an empty list of delimiters which turns of the line splitting behavior.
FOR would ignore a line on which first substring (entire file name in this case) would begin with a semicolon being by default the end of line character. A file name cannot contain a vertical bar. The option eol=|
defines the end of line character with the character |
to make sure that no file name is ignored by FOR.
A file extension is by Microsoft definition everything from last dot after last directory separator \
or from beginning of a string on this string not containing a backslash at all to end of the string. .1
, .2
, ... are the file extensions in file name string assigned to the loop variable I
.
The file name being everything left to last dot before version number is assigned to the loop variable CurrentName
and the version number with the dot at beginning to the environment variable CurrentNumber
while delayed variable expansion is still disabled to process correct also file names with one more exclamation marks in name.
Now is enabled delayed variable expansion. Please read this answer for more details about the commands SETLOCAL and ENDLOCAL as there is much more than by cmd.exe
in background on execution of setlocal EnableDelayedExpansion
which is very important to know for the further processing of the file name in the loop.
There is compared case-insensitive the current file name with the file name assigned last to the environment variable LastName
. See symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files for a detailed description how such a string comparison is done by command IF.
The current file name is from another version of a file if the two compared file names have case-insensitive identical. In this case the version numbers must be compared by converting the current and the last version number to 32-bit signed integer values and find out if the current file name has a greater number than the file of which version number is assigned to the environment variable LastNumber
. The dot of the file extension is removed using a string substitution to really compare two integer numbers.
ATTENTION 2:
IF on usage of comparison operator GTR interprets a number string with leading 0
as octal number. A version number string like 008
or 019
would be interpreted as invalid octal number resulting in using the integer value 0
for the comparison. A version number string like 010
would be interpreted as octal number 10
being decimal number 8
. The code of the batch file would require additional command lines if version number strings with one or more leading zeros could exist too.
The version number of the current file name is assigned to the environment variable LastNumber
after restoring previous environment with command ENDLOCAL if it is greater than the greatest version number for the current file. Otherwise just the previous environment is restored before processing the next file name.
In case of the current file name is different to previous file name, the previous file name with greatest version number is output first if not being the first file name processed inside the loop. Then the previous environment is restored and current file name as well as the current version number are assigned to the appropriate loop variables.
The name of the last file with its greatest version number must be finally output also for being written into the list file.
All output file names are written into the specified list file by using a command block for the entire FOR loop and the additional IF command below the FOR loop. The list file is opened already before running any command inside the entire block and closed finally on last command of the command block was executed by cmd
. There could be no files found at all in the user specified directory. The empty list file is deleted in this use case.
It looks like there should be started as separate, parallel executed process the executable trail_gen.exe
being stored in the batch file directory by cmd.exe
with calling CreateProcess
with the batch file directory respectively the executable directory as current working directory for trail_gen.exe
. The last but one command line does this with Trail generator
as title for the console window if the started executable is a Windows console and not a Windows GUI application.
There could be used also the following command line to start trail_gen.exe
:
start "Trail generator" /D "%WorkingDirectory%" "%~dp0trail_gen.exe"
That would result in starting trail_gen.exe
in batch file directory with current working directory for this executable being the user specified directory.
Last the batch file restores the initial environment as it existed on starting the batch file which results in closing the console window on batch file started with a double click and starting therefore implicit cmd.exe
with option /c
to run the batch file and then close itself.
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 which is the fully qualified directory path of the batch file always ending with a backslash.
cd /?
cls /?
del /?
dir /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
set /?
setlocal /?