I have written a batch file that I use for file management. The batch file parses an .XML database to get a list of base filenames, then allows the user to move/copy those specific files into a new directory. The program prompts the user for a source directory and the name of the .XML file. I would like the program to default the variables to the last used entry, even if the previous CMD session has closed. My solution has been to ask the user for each variable at the beginning of the program, then write those variables to a separate batch file called param.bat at the end like this:
@echo off set SOURCEDIR=NOT SET set XMLFILE=NOT SET if exist param.bat call param.bat set /p SOURCEDIR=The current source directory is %SOURCEDIR%. Please input new directory or press [Enter] for no change. set /p XMLFILE=The current XML database is %XMLFILE%. Please input new database or press [Enter] for no change. REM {Rest of program goes here} echo @echo off>param.bat echo set SOURCEDIR=%SOURCEDIR%>>param.bat echo set XMLFILE=%XMLFILE%>>param.bat :END I was hoping for a more elegant solution that does not require a separate batch file and allows me to store the variable data within the primary batch file itself. Any thoughts?
72 Answers
@echo off setlocal dir /r "%~f0" | findstr /c:" %~nx0:settings" 2>nul >nul && ( for /f "usebackq delims=" %%A in ("%~f0:settings") do set %%A ) if defined SOURCEDIR echo The current source directory is %SOURCEDIR%. set /p "SOURCEDIR= Please input new directory or press [Enter] for no change. " if defined XMLFILE echo The current XML database is %XMLFILE%. set /p "XMLFILE=Please input new database or press [Enter] for no change. " ( echo SOURCEDIR=%SOURCEDIR% echo XMLFILE=%XMLFILE% ) > "%~f0:settings" This uses the Alternate Data Stream (ADS) of the batchfile to save the settings. NTFS file system is required. The ADS stream is lost if the batchfile is copied to a file system other than NTFS.
The dir piped to findstr is to determine if the stream does exist before trying to read from it. This helps to avoid an error message from the for loop if the ADS does not exist.
The for loop sets the variable names and values read from the ADS.
Finally, the variables are saved to the ADS.
Note:
%~f0is full path to the batchfile. Seefor /?about all modifiers available.%~f0:settingsis the batchfile with ADS named settings.dir /rdisplays files and those with ADS.
Important:
Any idea involving writing to the batchfile could result in file corruption so would certainly advise a backup of the batchfile.
There is one way to save variables itself on the bat file, but, you need replace :END to :EOF
:EOF have a good explained in this link .:|:. see Where does GOTO :EOF return to?
Also, this work in fat32/ntfs file system!
You can write the variables in your bat file, and read when needs:
Obs.: Sorry my limited English
@echo off & setlocal enabledelayedexpansion set "bat_file="%temp%\new_bat_with_new_var.tmp"" & type nul >!bat_file! & set "nop=ot Se" for /f %%a in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo 0x40"') do set "delim=%%a" type "%~f0"| findstr "!delim!"| find /v /i "echo" >nul || for %%s in (SOURCEDIR XMLFILE) do set "%%s=N!nop!t" if defined SOURCEDIR echo/!SOURCEDIR!%delim%!XMLFILE!%delim%>>"%~f0" for /f "delims=%delim% tokens=1,2" %%a in ('type "%~f0"^| findstr /l "!delim!"^| find /v /i "echo"') do ( set /p "SOURCEDIR=The current source directory is %%~a. Please input new directory or press [Enter] for no change: " set /p "XMLFILE=The current XML database is %%~b. Please input new database or press [Enter] for no change: " if /i "!old_string!" neq "!SOURCEDIR!!delim!!XMLFILE!!delim!" ( type "%~f0"| findstr /vic:"%%~a!delim!%%~b!delim!">>!bat_file!" copy /y !bat_file! "%~f0" >nul echo/!SOURCEDIR!!delim!!XMLFILE!!delim!>>%~f0" goto :_continue_: )) :_continue_: rem :| Rest of program goes here | replace/change last command [goto :END] to [goto :EOF] goto :EOF rem :| Left 2 line blank above, because your variable will be save/read in next line above here |: