I have a batch file as under:
#echo off
"C:\Program Files\WinZip\WINZIP32.EXE" -min -a -ex "C:\Documents and Settings\vipul\Desktop\vipul.zip" files vipul.xls
copy vipul.zip "C:\Documents and Settings\vipul\Desktop\My briefcase"
copy vipul.zip "E:\Valuations\2009"
exit
HERE vipul.xls is the file on my desktop which is to be copied to my briefcase and same is to be ziiped and then sent to E\valu...folder.
Alteration i want here is as under:
every time the file name is getting changed, e.g. it may be sanj.xls or lago.xls and so on. (in place of vipul.xls), so how i can do this?
Just like there is printdir.bat file in xp
You could have this batch file which works for any file with .xlsextension:
#echo off
"C:\Program Files\WinZip\WINZIP32.EXE" -min -a -ex "C:\Documents and Settings\vipul\Desktop\worksheets.zip" files *.xls
copy worksheets.zip "C:\Documents and Settings\vipul\Desktop\My briefcase"
copy worksheets.zip "E:\Valuations\2009"
exit
Or, if just one that files can exist in some time:
#echo off
set filename=
if exists vipul.xls set filename=vipul
if exists sanj.xls set filename=sanj
if exists lago.xls set filename=lago
if "%filename%" == "" goto end
"C:\Program Files\WinZip\WINZIP32.EXE" -min -a -ex "C:\Documents and Settings\vipul\Desktop\%filename%.zip" files %filename%.xls
copy %filename%.zip "C:\Documents and Settings\vipul\Desktop\My briefcase"
copy %filename%.zip "E:\Valuations\2009"
exit
:end
Its not tested, but this should help you:
#echo off
REM check if supplied file name actaully exists
IF "%1"=="" GOTO END
IF NOT EXIST "%1" GOTO END
REM define output file name. Use supplied files name without extension and add ".zip"
SET OutputPath=C:\Documents and Settings\vipul\Desktop\%~n1.zip
"C:\Program Files\WinZip\WINZIP32.EXE" -min -a -ex "%OutputPath%" files "%1"
copy "%OutputPath%" "C:\Documents and Settings\vipul\Desktop\My briefcase"
copy "%OutputPath%" "E:\Valuations\2009"
:END
This batch uses the first command line parameter (%1) as input for the file to package and copy.
The first IF statements check if the file is valid. The SET command set a variable with the name of the file to create (the zip file). The remaining part is mainly the code you already have, but now uses the variables.
EDIT:
To call the batch programm, lets name it package.bat, use a syntax like this:
package "C:\Documents and Settings\vipul\Desktop\vipul.xls"
or
package "C:\Documents and Settings\vipul\Desktop\sanj.xls"
You can also use drag 'n drop and simply drop the file you want to process on the batch file package.bat to start it.
If it doesn't work, add a comment.
EDIT:
To use this batch file in your send to context menu do the following steps:
save the above code in a file and name package.bat (or anything else you want)
put in a location you want.
create a link to the batch file package.bat (right click on the file, chose create link)
move the created link file to your Send to folder (e.g. C:\Documents and Settings\vipul\SendTo
now you can select any file you want and chose the batch file command from your context menu->send to
Hope that helps.
Related
I have a folder full of zip files. Those zip files sometimes contain zip files, that sometimes contain zip files within them, and so on. I am trying to write a batch file that I can paste into the top folder containing all the zips, and when it runs it will unzip all the nested zip files, and within sub-directories, all the way down, and delete the zips once they have been successfully extracted. The full file paths need to be preserved. If there is an error and a file cannot be extracted then it should not be deleted and the file and file path need to be printed to a text file.
So far I have this:
#ECHO ON
SET source=%cd%
FOR /F "TOKENS=*" %%F IN ('DIR /S /B "%source%\*.zip"') DO "C:\Program Files\7-Zip\7z.exe" x "%%~fF" -o"%%~pF\"
EXIT
Which I can drop into a folder and run, it will unzip the first level of zips but none of the nested zips inside. That's the first hurdle.
The next hurdle would be to delete the successfully extracted zips. And last, not to delete any zips that could not be extracted and print their name and/or path to a text file.
Any suggestions or chunks of code are appreciated. Or if there's a better way to do this entirely.
**** UPDATED ****
Mofi posted an answer that looks like it's working except for one piece:
When a ZIP is extracted, it needs to be extracted to a folder with the same name, so I can still follow the structure.
Starting Example:
[Top Level Folder Holding Zips] (folder)
--ExampleZip.zip
---FileInZip.txt
---FileinZip2.txt
--ExampleZip2.zip
---Folder1 (folder)
----ExampleZip3.zip
-----FileinZip3.txt
-----FileinZip4.txt
---ExampleZip4.zip
----FileinZip5.txt
----FileinZip6.txt
Needs to become this:
[Top Level Folder Holding Zips] (folder)
--ExampleZip (folder)
---FileInZip.txt
---FileinZip2.txt
--ExampleZip2 (folder)
---Folder1 (folder)
----ExampleZip3 (folder)
-----FileinZip3.txt
-----FileinZip4.txt
---ExampleZip4 (folder)
----FileinZip5.txt
----FileinZip6.txt
So the full structure is still visible.
I think the top answer in this question shows what I need to include: Extract zip contents into directory with same name as zip file, retain directory structure
This part:
SET "filename=%~1"
SET dirName=%filename:~0,-4%
7z x -o"%dirName%" "%filename%"
Needs to be smashed in there somewhere. Or it seems like there should be a switch for 7Zip that does it, since you can do this from the context menu with "Extract to *" I thought that's what the "extract with full paths" command does but that must have something to do with the -o switch, specifying output path? How do I specify the output path to be a folder with the same name as the input zip? Or merge the answer from that question I linked with Mofi's answer?
*** UPDATED AGAIN ***
I thought there was an issue with the batch file ignoring ZIP files with underscores in the name, but that was a coincidence and it was actually ignoring ZIP files without the Archive file attribute set.
Mofi suggested another fix for that which worked, but the batch file is not extracting nested zips that needed the Archive file attribute set.
This does kind of work, in that I can manually execute the batch file a few times and it will work it's way through everything in the folder, but the loop calculation does not seem to work, or is calculating/terminating before the batch file sets the Archive attribute for all zip files?
Here is the current version I'm working with:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ErrorOutput="
set "LoopCount=20"
rem The current directory is used on batch file being called without
rem a base folder path or with just one or more double quotes.
set "BaseFolder=%~1"
if defined BaseFolder set "BaseFolder=%BaseFolder:"=%"
if not defined BaseFolder set "BaseFolder=%CD%" & goto VerifyFolderPath
rem Make sure the folder path contains backslashes and not forward slashes
rem and does not contain wildcard characters or redirection operators or a
rem horizontal tab character after removing all double quotes.
set "BaseFolder=%BaseFolder:/=\%"
for /F "delims=*?|<> " %%I in ("%BaseFolder%") do if not "%BaseFolder%" == "%%I" (
echo ERROR: %~nx0 must be called with a valid folder path.
echo "%~1" is not a valid folder path.
set "ErrorOutput=1"
goto EndBatch
)
rem Get full folder path in case of the folder was specified with
rem a relative path. If the folder path references the root of a
rem drive like on using "C:\" or just "\", redefine the folder
rem path with full path for root of the (current) drive.
for %%I in ("%BaseFolder%") do set "BaseFolder=%%~fI"
:VerifyFolderPath
rem The base folder path must end with a backslash for verification.
if not "%BaseFolder:~-1%" == "\" set "BaseFolder=%BaseFolder%\"
rem Verify the existence of the folder. The code above processed also
rem folder paths of folders not existing at all and also invalid folder
rem paths containing for example a colon not (only) after drive letter.
if not exist "%BaseFolder%" (
echo ERROR: Folder "%BaseFolder%" does not exist.
set "ErrorOutput=1"
goto EndBatch
)
rem Make sure to process all ZIP files existing in base folder and all
rem its subfolders by setting archive file attribute on all ZIP files.
%SystemRoot%\System32\attrib.exe +A /S "%BaseFolder%*.zip"
rem Process all *.zip files found in base folder and all its subfolders
rem which have the archive file attribute set. *.zip files with archive
rem file attribute not set are ignored to avoid an endless running loop
rem if a ZIP archive file cannot be extracted successfully with reason(s)
rem output by 7-Zip or if the ZIP file cannot be deleted after successful
rem extraction of the archive. The archive extraction loop runs are limited
rem additionally by a loop counter as defined at top of the batch file for
rem 100% safety on prevention of an endless loop execution.
:ExtractArchives
set "ArchiveProcessed="
for /F "delims=" %%I in ('dir "%BaseFolder%*.zip" /AA-D /B /S 2^>nul') do (
set "ArchiveProcessed=1"
echo Extracting archive: "%%I"
"%ProgramFiles%\7-Zip\7z.exe" x -bd -bso0 -o"%%~dpnI\" -spd -y -- "%%I"
#pause
if errorlevel 255 set "ErrorOutput=1" & goto EndBatch
if errorlevel 1 (
set "ErrorOutput=1"
%SystemRoot%\System32\attrib.exe -A "%%I"
) else (
del /A /F "%%I"
if exist "%%I" (
echo ERROR: Failed to delete: "%%I"
set "ErrorOutput=1"
%SystemRoot%\System32\attrib.exe -A "%%I"
)
)
)
if not defined ArchiveProcessed goto EndBatch
set /A LoopCount-=1
if not LoopCount == 0 goto ExtractArchives
:EndBatch
if defined ErrorOutput echo/& pause
endlocal
echo[
echo[
echo If no errors are displayed above, everything extracted successfully. Remember to delete the batch file once you are done.
#pause
It is rare that there would be maybe 10 or 20 layers of nested zips, so a quick and dirty fix may be just somehow looping the whole batch file 10 or 20 times, unless that is a bad idea or there is a more elegant way to do it.
The task to recursively extract all ZIP archives including nested ZIP archives inside a ZIP archive can be achieved by running the ZIP archive file extraction process in a loop until no ZIP file exists anymore. But there must be at least two use cases taken into account to avoid an endless running archive extraction loop:
The extraction of a ZIP archive file fails for whatever reason. 7-Zip outputs information about the error reason(s). Such a ZIP file should not be processed a second time.
The deletion of a successfully extracted ZIP file fails for whatever reason. The ZIP file should not be processed once again.
The solution is processing only ZIP files with archive file attribute set as done automatically by Windows on creating, renaming or modifying a file and remove the archive file attribute on every ZIP file on which the extraction process or the deletion of the file failed to avoid processing the ZIP file again.
The archive file attribute is set on all *.zip files on directory tree to process before starting the archive files extraction process to make sure that really all existing *.zip files are processed at least once. The archive file attribute is also set on all *.zip files in output directory of a completely successfully processed ZIP archive file to make sure that even *.zip files inside a ZIP file with archive file attribute not set after extraction are processed also on next archive file extraction loop run.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ErrorOutput="
set "LoopCount=20"
rem The current directory is used on batch file being called without
rem a base folder path or with just one or more double quotes.
set "BaseFolder=%~1"
if defined BaseFolder set "BaseFolder=%BaseFolder:"=%"
if not defined BaseFolder set "BaseFolder=%CD%" & goto VerifyFolderPath
rem Make sure the folder path contains backslashes and not forward slashes
rem and does not contain wildcard characters or redirection operators or a
rem horizontal tab character after removing all double quotes.
set "BaseFolder=%BaseFolder:/=\%"
for /F "delims=*?|<> " %%I in ("%BaseFolder%") do if not "%BaseFolder%" == "%%I" (
echo ERROR: %~nx0 must be called with a valid folder path.
echo "%~1" is not a valid folder path.
set "ErrorOutput=1"
goto EndBatch
)
rem Get full folder path in case of the folder was specified with
rem a relative path. If the folder path references the root of a
rem drive like on using "C:\" or just "\", redefine the folder
rem path with full path for root of the (current) drive.
for %%I in ("%BaseFolder%") do set "BaseFolder=%%~fI"
:VerifyFolderPath
rem The base folder path must end with a backslash for verification.
if not "%BaseFolder:~-1%" == "\" set "BaseFolder=%BaseFolder%\"
rem Verify the existence of the folder. The code above processed also
rem folder paths of folders not existing at all and also invalid folder
rem paths containing for example a colon not (only) after drive letter.
if not exist "%BaseFolder%" (
echo ERROR: Folder "%BaseFolder%" does not exist.
set "ErrorOutput=1"
goto EndBatch
)
rem Make sure to process all ZIP files existing in base folder and all
rem its subfolders by setting archive file attribute on all ZIP files.
%SystemRoot%\System32\attrib.exe +A /S "%BaseFolder%*.zip" >nul
rem Process all *.zip files found in base folder and all its subfolders
rem which have the archive file attribute set. *.zip files with archive
rem file attribute not set are ignored to avoid an endless running loop
rem if a ZIP archive file cannot be extracted successfully with reason(s)
rem output by 7-Zip or if the ZIP file cannot be deleted after successful
rem extraction of the archive. The archive extraction loop runs are limited
rem additionally by a loop counter as defined at top of the batch file for
rem 100% safety on prevention of an endless loop execution.
:ExtractArchives
set "ArchiveProcessed="
for /F "delims=" %%I in ('dir "%BaseFolder%*.zip" /AA-D /B /S 2^>nul') do (
set "ArchiveProcessed=1"
echo Extracting archive: "%%I"
"%ProgramFiles%\7-Zip\7z.exe" x -bd -bso0 -o"%%~dpI" -spd -y -- "%%I"
if errorlevel 255 set "ErrorOutput=1" & goto EndBatch
if errorlevel 1 (
set "ErrorOutput=1"
%SystemRoot%\System32\attrib.exe -A "%%I"
) else (
%SystemRoot%\System32\attrib.exe +A /S "%%~dpnI\*.zip" >nul
del /A /F "%%I"
if exist "%%I" (
echo ERROR: Failed to delete: "%%I"
set "ErrorOutput=1"
%SystemRoot%\System32\attrib.exe -A "%%I"
)
)
)
if not defined ArchiveProcessed goto EndBatch
set /A LoopCount-=1
if not LoopCount == 0 goto ExtractArchives
:EndBatch
if defined ErrorOutput echo/& pause
endlocal
Note: There must be one horizontal tab character after "delims=*?|<> and " on line 16 of the batch file code and not a series of space characters as there will be after copying the code from browser window and pasting the code into a text editor window.
The batch file is commented with lines with command REM (remark). These comments should be read for understanding the code and then can be removed for a more efficient execution of the batch file by Windows command processor.
The 7-Zip switches used in code are explained by help of 7-Zip opened by double clicking on file 7-zip.chm or opening Help from within GUI window of started 7-Zip. On help tab Contents expand the list item Command Line Version and click on list item Switches to get displayed the help page Command Line Switches with all switches supported by currently used version of 7-Zip.
The batch file can be executed with a folder path as argument to process all ZIP files in this folder and all its subfolders. So it is possible to add to Send to context menu of Windows File Explorer a shortcut file which runs the batch file with the folder path passed by Windows File Explorer to the batch file as first argument. It would be also possible to registry the batch file as context menu option for Directory in Windows registry to be able to run the batch file easily from within any application supporting the Windows context menu handlers for a directory.
Edit after question edited: The command line running 7-Zip can be modified to:
"%ProgramFiles%\7-Zip\7z.exe" x -bd -bso0 -o"%%~dpnI\" -spe -spd -y -- "%%I"
Each ZIP file is extracted with this command line into a subfolder in folder of the ZIP file with name of the ZIP file because of replacing -o"%%~dpI" by -o"%%~dpnI\". The additional 7-Zip switch -spe avoids duplicating the folder name if the ZIP file contains at top level a folder with same name as the ZIP file. So if Example3.zip contains at top level the folder Example3, the files are extracted to folder Example3 and not to folder Example3\Example3 as it would occur without usage of option -spe.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
attrib /?
call /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rem /?
set /?
setlocal /?
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
Using Groovy, or Ant
This would be a lot easier using Apache Ant or, better still, the Groovy AntBuilder.
e.g. this Groovy script will unzip all the top leval zip files then delete them:
new AntBuilder().with {
def sourceRoot = '.'
// Unzip all .zip files in / underneath sourceRoot
unzip( dest: 'some-folder' ) {
fileset( dir: sourceRoot ) {
include name: "**/*.zip"
}
}
// Unzip throws an exception on failure.
// Delete all .zip files in / underneath sourceRoot
delete {
fileset( dir: sourceRoot, includes: '**/*.zip' )
}
}
You'll need to keep scanning the destination folder for zips, and repeating the above process, until everythings unzipped. You may also find it useful to use a FileScanner.
AntBuilder throws an exception if anything fails, so you can avoid deleting archives that fail to unzip. AntBuilder will also log it's progress, using the standard Java logging mechanisms. You can tell it the level of detail you want, or supress it completely
The full AntBuilder documentation is here:
http://docs.groovy-lang.org/latest/html/documentation/ant-builder.html
Using a fileScanner
Example from the Groovy AntBuilder documentation:
// let's create a scanner of filesets
def scanner = ant.fileScanner {
fileset(dir:"src/test") {
include(name:"**/My*.groovy")
}
}
// now let's iterate over
def found = false
for (f in scanner) {
println("Found file $f")
found = true
assert f instanceof File
assert f.name.endsWith(".groovy")
}
assert found
Putting it together
It's not a huge leap to combine a filesScanner with an AntBuilder to get the job done. I suspect it will be a lot easier than doing it with a batch script.
Finally managed to write a batch file that can unzip nested zips, keeping the archive file structure intact!
logic is that, run recursively until all the zip files are unzipped. Number of iterations default is 5, and can be passed as cmd arg "extract.bat 3". may be changed to a while loop until hit file not found exception. And most importantly delete the archive file after extraction, so, we don't get into endless loop!
But follow the rules below
it uses 7z, make sure in the cmd window 7z can be run, that is in the path
zip file names cannot have spaces. make sure of that and ext is zip
copy the zip file to a directory where there are no other zip files
And only .zip ext, you may change that to rar or anything in the batch file
Here is the batch file
Rem Nested unzip - #sivakd
echo off
if "%1"=="" (set iter=5) else (set iter=%1)
echo Running %iter% iterations
for /l %%x in (1, 1, %iter%) do (
dir *.zip /s /b > ziplist.txt
for /F %%f in (ziplist.txt) do (
7z x %%f -o%%~dpnf -y & del /f %%f
)
del ziplist.txt
)
okay, so I have written a little script of code :
for /R %%f in (*.acd) do C:\Users\jelle\Downloads\quickbms\quickbms.exe D:\assetto_corsa_acd.bms %%f "\data"
but the problem is that the file data.acd will be extracted using quickbms.exe to a data folder in the main folder my batch file is located in stead of in the /data folder located in the folder where the data.acd file is, so x:\carname(folder_with_data.acd_in_it)\data
but i can't get that to work,
so my question is how do i get quickbms to extract the acd file to the folder where the acd file is located instead of where the batch file is located?
Also note that quickbms is in my path
Thanks in advance.
Your posted script appears to be running two lines instead of only one.
Based on the following usage:
quickbms.exe [options] <script.BMS> <input_archive/folder> [output_folder]
I would suggest something like this:
#Echo Off
Rem Full path to QuickBMS
Set "eBMS=%UserProfile%\Downloads\quickbms\quickbms.exe"
Rem Full path to BMS script
Set "sBMS=D:\assetto_corsa_acd.BMS"
Rem BMS Options
Set "oBMS=-o -d"
Rem The source directory path to recurse (. is current, %~1 is arg[0])
Set "sDIR=."
Rem The sourcefile extension
Set "sEXT=.acd"
Rem The output directory path (.\ relevant to current, %~2 is arg[1])
Set "tOUT=.\data"
For /R "%sDIR%" %%A In (*%sEXT%) Do "%eBMS%" %oBMS% "%sBMS%" "%%A" "%tOUT%"
Fill in the Set command lines according to the Remarks and give it a try reporting back any issues as necessary.
So I have the batch file below.
#ECHO OFF
FOR %%I IN (.) DO SET FolderName=%%~nxI
MKDIR "C:\%FolderName%"
for %%i in (%*) do (
move "%%~i" "C:\%FolderName%"
)
So when I drag and drop multiple files into the batch file, it will take the name of the folder that holds the files that I drag and drop and make a new folder at C:\ with the same name and then move the files into the new folder at C:\
Example: The folder that holds the files that I want to move is name Shop. Then the folder Shop is located at
...\ground\bell\tower\Shop
Using the batch file will make a new folder name Shop at C:\
Example
C:\Shop
The batch files works when I drag and drop about 100 files at once. The problem is that when I drag and drop 300 files at once, it returns the Error that says "The filename or extension is too long". I am able to move the files manually so I know that it can not be cause by a filename being too long.
Then I made a new batch file thinking maybe it is a problem with the move command or my for loop. So I wrote the batch file below.
#echo off
FOR %%I IN (.) DO SET FolderName=%%~nxI
MKDIR "C:\%FolderName%"
MOVE "%cd%\*.*" "C:\%FolderName%"
Now the second batch file above works just about the same as the first batch file. Just that with the second batch file, I only need to drag and drop one file from the folder that I want to move and it will move all the files in the first folder to a new folder at C:\ even if the first folder had 1000 files.
My question is why does the first batch file fail if I drag and drop too many files at once. Using the second batch file work, so it can not be because of the move command or is it? Since I am moving all the files from one folder to the other, the second batch file fits my need and was wondering if there will be any problems with the second batch file or a better way of doing this.
When you Drag-n-Drop Files on you Bat File, your Bat is actually called as if you would have called it in your command prompt. So if you drag three files on your Bat i.e.
Testfile.txt
Testfile.md
Testfile.jpg
Then actually your Bat is called like this:
C:\MyBatch.BAT Testfile.txt Testfile.md Testfile.jpg
If you call more it is obviously something like:
C:\MyBatch.BAT Testfile.txt Testfile.md Testfile.jpg Testfile01.txt Testfile01.md Testfile01.jpg Testfile02.txt Testfile02.md Testfile02.jpg Testfile03.txt Testfile03.md Testfile03.jpg Testfile04.txt Testfile04.md Testfile04.jpg Testfile05.txt Testfile05.md Testfile05.jpg etc...
Ah, can you read the rest of the line? Ok, this is not as long as 1000 Files but get the point what the difference is in your scripts. Your command line buffer will not be able to capture that much input.
Actually the size of how many characters you can enter in you command prompt varies a bit from system to system, but there was something like 8k in winXP, i reckon it is still the same.
http://support.microsoft.com/kb/830473 <-- that could help more concerning max.
And since the length of your command prompt is so "short" you have to find different methods for longer file trails - as you did - you could also overcome this, if you output the files you want to copy in a text file and then use that as input for your copy bat.
dir /b >filelist.txt
so now that you have this file list, then you just read the text file line by line:
for /f "delims=" %%i in (filelist.txt) do echo D|xcopy "C:\FolderName\%%i" "c:\temp\%%i" /i /z /y
so this will actually read your file list.txt and will (for each filename in list) press D key and pipes it to the XCopy command.
So piping a filelist to your command is a much better way, where actually in your case, if you really want the whole dir and not just a selection, copying directories is faster than copying file by file.
Hope you Question is answered.
If I am not mistaken, you are trying to create a folder with the parent folder as name. So before you ask again the same question in another post, I will code what you are seeking.
#echo off
setlocal
set "destination=c:\destination"
for %%i in (%~1) do set "parent=%%~pi" &goto:next
:next
for %%i in ("%parent:~0,-1%") do set "parent=%%~nxi"
for %%i in (%*) do (
echo:
if not exist %destination%\%parent%\nul ( mkdir "%destination%\%parent%" )
move "%%~i" "%destination%%parent%"
)
In addition, a command with many arguments is not a problem in the previous code.
For example: Write a batch file with the following code
#echo off
setlocal
set "destination=c:\destination"
for %%i in (%~1) do set "parent=%%~pi" &goto:next
:next
for %%i in ("%parent:~0,-1%") do set "parent=%%~nxi"
for %%i in (%*) do (
echo:
if not exist %destination%\%parent%\nul (echo mkdir "%destination%\%parent%")
echo move "%%~i" "%destination%%parent%"
)
call it test-move.bat and put the following long command-line of 250 parameters in cmd:
test-move.bat TestFile001.txt TestFile002.txt TestFile003.txt TestFile004.txt TestFile005.txt TestFile006.txt TestFile007.txt TestFile008.txt TestFile009.txt TestFile010.txt TestFile011.txt TestFile012.txt TestFile013.txt TestFile014.txt TestFile015.txt TestFile016.txt TestFile017.txt TestFile018.txt TestFile019.txt TestFile020.txt TestFile021.txt TestFile022.txt TestFile023.txt TestFile024.txt TestFile025.txt TestFile026.txt TestFile027.txt TestFile028.txt TestFile029.txt TestFile030.txt TestFile031.txt TestFile032.txt TestFile033.txt TestFile034.txt TestFile035.txt TestFile036.txt TestFile037.txt TestFile038.txt TestFile039.txt TestFile040.txt TestFile041.txt TestFile042.txt TestFile043.txt TestFile044.txt TestFile045.txt TestFile046.txt TestFile047.txt TestFile048.txt TestFile049.txt TestFile050.txt TestFile051.txt TestFile052.txt TestFile053.txt TestFile054.txt TestFile055.txt TestFile056.txt TestFile057.txt TestFile058.txt TestFile059.txt TestFile060.txt TestFile061.txt TestFile062.txt TestFile063.txt TestFile064.txt TestFile065.txt TestFile066.txt TestFile067.txt TestFile068.txt TestFile069.txt TestFile070.txt TestFile071.txt TestFile072.txt TestFile073.txt TestFile074.txt TestFile075.txt TestFile076.txt TestFile077.txt TestFile078.txt TestFile079.txt TestFile080.txt TestFile081.txt TestFile082.txt TestFile083.txt TestFile084.txt TestFile085.txt TestFile086.txt TestFile087.txt TestFile088.txt TestFile089.txt TestFile090.txt TestFile091.txt TestFile092.txt TestFile093.txt TestFile094.txt TestFile095.txt TestFile096.txt TestFile097.txt TestFile098.txt TestFile099.txt TestFile100.txt TestFile101.txt TestFile102.txt TestFile103.txt TestFile104.txt TestFile105.txt TestFile106.txt TestFile107.txt TestFile108.txt TestFile109.txt TestFile110.txt TestFile111.txt TestFile112.txt TestFile113.txt TestFile114.txt TestFile115.txt TestFile116.txt TestFile117.txt TestFile118.txt TestFile119.txt TestFile120.txt TestFile121.txt TestFile122.txt TestFile123.txt TestFile124.txt TestFile125.txt TestFile126.txt TestFile127.txt TestFile128.txt TestFile129.txt TestFile130.txt TestFile131.txt TestFile132.txt TestFile133.txt TestFile134.txt TestFile135.txt TestFile136.txt TestFile137.txt TestFile138.txt TestFile139.txt TestFile140.txt TestFile141.txt TestFile142.txt TestFile143.txt TestFile144.txt TestFile145.txt TestFile146.txt TestFile147.txt TestFile148.txt TestFile149.txt TestFile150.txt TestFile151.txt TestFile152.txt TestFile153.txt TestFile154.txt TestFile155.txt TestFile156.txt TestFile157.txt TestFile158.txt TestFile159.txt TestFile160.txt TestFile161.txt TestFile162.txt TestFile163.txt TestFile164.txt TestFile165.txt TestFile166.txt TestFile167.txt TestFile168.txt TestFile169.txt TestFile170.txt TestFile171.txt TestFile172.txt TestFile173.txt TestFile174.txt TestFile175.txt TestFile176.txt TestFile177.txt TestFile178.txt TestFile179.txt TestFile180.txt TestFile181.txt TestFile182.txt TestFile183.txt TestFile184.txt TestFile185.txt TestFile186.txt TestFile187.txt TestFile188.txt TestFile189.txt TestFile190.txt TestFile191.txt TestFile192.txt TestFile193.txt TestFile194.txt TestFile195.txt TestFile196.txt TestFile197.txt TestFile198.txt TestFile199.txt TestFile200.txt TestFile201.txt TestFile202.txt TestFile203.txt TestFile204.txt TestFile205.txt TestFile206.txt TestFile207.txt TestFile208.txt TestFile209.txt TestFile210.txt TestFile211.txt TestFile212.txt TestFile213.txt TestFile214.txt TestFile215.txt TestFile216.txt TestFile217.txt TestFile218.txt TestFile219.txt TestFile220.txt TestFile221.txt TestFile222.txt TestFile223.txt TestFile224.txt TestFile225.txt TestFile226.txt TestFile227.txt TestFile228.txt TestFile229.txt TestFile230.txt TestFile231.txt TestFile232.txt TestFile233.txt TestFile234.txt TestFile235.txt TestFile236.txt TestFile237.txt TestFile238.txt TestFile239.txt TestFile240.txt TestFile241.txt TestFile242.txt TestFile243.txt TestFile244.txt TestFile245.txt TestFile246.txt TestFile247.txt TestFile248.txt TestFile249.txt TestFile250.txt
What would the contents of a bat file be if I want the following
If a file exists (file name and location)
Then delete the file and then restart the computer
It's pretty straightforward -
#echo off
set FileToCheck=NAME_OF_THE_FILE_HERE
if not exist %FileToCheck% goto done
del %FileToCheck%
shutdown /r
:done
You could also use set FileToCheck=%1 instead of hard-coding the filename in your batch file if you want to pass the filename to look for as a command line parameter, i.e. (assuming your batch file is named foo.bat):
c:\>foo RemoveMeAndRebootIfIExist.txt
e.g. I want to run a windows batch file, say upgrade.bat, which copies a bunch of files from a source directory to the directory that the batch file is in. Problem is, one of the files copied might be a newer version of upgrade.bat, so that the batch file will overwrite itself while its still running.
This seems to result in some unpredictable behavior of batch file execution, so I want to avoid copying over a batch file which is still running. Ideally, I want the existing version of upgrade.bat to run until it is finished, and next time run the new version. Are there any (simple) ways to achieve this ?
#ECHO OFF
SETLOCAL
IF /i NOT "%~dp0"=="%temp%\" (
COPY /y "%~dpnx0" "%temp%\%~nx0" >nul
"%temp%\%~nx0"
)
ECHO Now we run the rest of the original UPGRADE.BAT
This sequence of lines at the start of upgrade.bat should work.
See whether we're running from a copy in %temp%. If not, then copy this file to temp & run it from there.
Hence the batch actually runs from %temp% and the original version may be overwritten.
In order to do that, the following requirements must be satisfied:
The overwrite of the Batch file for the newer version of itself must be the last command of the Batch file, so the next command after the copy must be an exit /B or exit.
Previous commands must be loaded in memory before they are executed. This is easily done by enclosing them in parentheses.
That is:
#echo off
rem Do program business here...
echo Anything
rem Parse/load following commands before execute they:
(
rem Copy many files, probably a newer version of myself
xcopy /Y *.*
rem You may execute other commands here...
echo Files copied!
rem Terminate *this version* of the running Batch file
exit /B
)
You can run the copy as the last operation using the start command to launch it from another terminal. Check this example, specially the last lines.
#echo off
set CUR_FILE=batman.bat
set FOUND_EQUAL="FALSE"
set FROM_DIR=c:\temp\galeria\
SETLOCAL DisableDelayedExpansion
FOR /R %FROM_DIR% %%F IN (*) DO (
SET "p=%%F"
SETLOCAL EnableDelayedExpansion
SET ABC=!p:%FROM_DIR%=!
IF NOT !ABC! == !CUR_FILE! (
echo copying %%F
copy "%%F" .
)
ENDLOCAL
)
echo trying to copy file with the same name [last operation]
start copy "%FROM_DIR%%CUR_FILE%" .
#echo off
cmd /c copy "C:\somepath\upgrade.bat" "%0" & %0
This would start a new cmd process and replace the current batch file with "C:\somepath\upgrade.bat" and restart the batch file
Would it be an option to tag each new version of the batch file with a version suffix and use a second batch file as a launcher?
For example say you are payload batch file is upgrade.bat, subsequent versions will be named as upgrade_001.bat, upgrade_002.bat, upgrade_003.bat .. or upgrade_201305122134 (suffix being yyyymmddHHMM), the new batch file launcher.bat would look for the latest batch upgrade file by looking for the one with the highest suffix and execute it
if NOT "%1"=="RUN" (
copy "%~0" temp_update.cmd
temp_update.cmd RUN
)
Just put this at the top of your cmd file
any name can be used for the temporary file.
Make the batch file copy itself to updateNow.bat and then run updateNow.bat:
So contents of update.bat is:
if %0 == update (
copy update.bat updateNow.bat
updateNow.bat
) else (
copy newUpdate.bat update.bat
)