So now i have 2 .bat files. one copies some file if it was updated ( robocopy C:\location C:\destination) and another one that executes a some kind of .exe file (start c:\BAT\fraps.exe) , now what i need is maybe a one file, so that WHEN a file was copied using "robocopy" the executive file would run automaticaly. So maybe there is a way to merge them into one or smth.
Errorlevels are set by robocopy: errorlevel 1 means that a file was successfully copied.
robocopy C:\location C:\destination
if errorlevel 1 if not errorlevel 2 start c:\BAT\fraps.exe
Here is proof of concept code - following extended comments:
#echo off
md test1
:loop
>test1\testfile.txt echo aaa
robocopy test1 test2
if errorlevel 1 if not errorlevel 2 pause
del test1\testfile.txt
goto :loop
Use /WAIT option, when the application is stared then it will wait until it terminates.
Use /B option, when application is started then it will not create a new window.
Example:
start /wait Command CALL D:\YourFirstScript.bat
start /wait program.exe
start /wait Command CALL X:\YourSecondScript.bat
It's a good idea to print a message before and after.
Example:
ECHO Starting program.
start /wait program.exe
ECHO Finished.
See below link for more details.
How do I launch multiple batch files from one batch file with dependency?
Note: When you run script as administrator then you need to set full path as the default is set to "C:\Windows\System32".
The easiest way to set is
start %~dp0Directory\program.exe
See for details about "%~dp0" here
What does %~dp0 mean, and how does it work?
This is my first post and I hope that this will help you.
Related
I would like to start 3 commands in the same window.
For now I have this batch but there are 3 different windows at each command.
start /d "c:\Program Files\myfolder" cmd /k cscript A
timeout /t 6 >nul
start /d "c:\Program Files\myfolder" cmd /k cscript B
timeout /t 6 >nul
start /wait /d "c:\PProgram Files\myfolder" cmd /k cscript C
What should I modify to have only one window? thanks
I think you can run a .bat file by changing the directory like so, cd C:\PATH\TO\DIRECTORY\WITH\FILE, then use call (file name here). This should work assuming that all the files are in the same directory, if not you'll just have to change the directory for each call method. If my code doesn't seem very helpful, check this page out https://superuser.com/a/1062322
Example Code
#echo off
cd PATH\TO\FILE\DIRECTORY
call FILE NAME
echo The file (file name here) has run!
pause
this code will make a call to the file and pause the terminal to keep it opened. You can take this code and make as many calls/cd's as you like. I hope this helped, If it doesn't work, please tell me what doesn't work and I'll try to fix it. Have a nice day :)
I have a folder xyz. It has a batch file which copies files from source directory abc to destination directory def. I am using copy with options /v /y.
Copy works absolutely fine. But I notice a strange or weird issue that additionally a copy of all the files copied from source to destination are present in folder xyz.
I started observing this issue after a system restart and not sure if its a one time issue. But I would like to know if someone has run into this issue before and what is the possible fix?
Here is the code:
#if not defined ECHO_ON echo off
SETLOCAL EnableDelayedExpansion
set arg1=%1
set arg2=%2
copy /v /y !arg1! !arg2!
call :getPath !arg1!
ren !arg2!\!_NAME_EXT! !_NAME!.svg
:getPath
set _NAME=%~n1
set _NAME_EXT=%~nx1
set _LOC=%~dp1
goto:eof
endlocal
Please note I am using copy and robocopy command (for some other copying operation) in same .bat file.
Is this something to be worried about?
(As I wrote things worked fine until restart.)
Your double Copy is because a batch script works line by line until it reaches an end of file marker or an exit instruction. A Call command returns back to the point just after the Call instruction. When it returns, there is no exit instruction or end of file marker until the bottom of your script, so the :getPath label is executed again.
There appears to have been absolutely no reason for EnableDelayedExpansion in your script, for Setting any variables or for a Call command. I have therefore simplified it as such:
#Echo Off
If "%~2"=="" Exit /B
If Not Exist "%~2\" MD "%~2" 2>Nul || Exit /B
If Exist "%~1" Copy /V /Y "%~1" "%~2\%~n1.svg"
I hope it helps you out.
i want to watch a folder on my Win7 64bit Machine for new pdf files - and print them autmatically when there is a pdf file in the folder. After printing, the pdf file should be moved in a subfolder. So, after some google research i did a small batch file.
cd "D:\print"
for %%i in (*.pdf) do (
"C:\Program Files\Tracker Software\PDF Viewer\PDFXCview.exe" /print "%%i"
timeout /T 10 /nobreak
move D:\print\*.pdf D:\print\printed
echo %%i
)
I stored this in folder d:\print as print.cmd . When i start the cmd by doubleclick, my printer starts working and the pdf file moves to the subfolder i defined (D:\print\printed).
To watch the folder, i had the idea to create a sheduled task that repeat this cmd-script all 5 minutes.
BUT:
This dont work, when the script is started via scheduled tasks, the printer is not working - the "movement" of the file instead, is working.
I entered in the scheduled task:
Program: C:\Windows\SysWOW64\cmd.exe
Argument: /c"d:\print\print.cmd"
Any idea, why i cant acces the printer via the scheduled task?
The printer is connected via usb.
Hope i could provide necessary information! Thanks for your answers!
Change this line: move D:\print\*.pdf to move /Y D:\print\%%i
Point the scheduled task to actually start your batch file instead of calling cmd and putting the path to your script in the arguments.
You could also edit the batch file and code it to loop every 5 minutes so you only have to start it once:
PushD %~dp0
:start
for %%i in ("D:\print\*.pdf") do (
"C:\Program Files\Tracker Software\PDF Viewer\PDFXCview.exe" /print "%%i"
move /y "%%i" "D:\print\printed"
echo %%i
)
timeout /T 300 /nobreak
goto start
I have a bunch of batch files that each start a bunch of executables to run concurrently. Each batch file starts 30 executables. When those 30 are done, I want the next batch of executables to run, again 30 at a time. The .exe's are called using the "start" command in the batch files and they work just fine - I can run the individual batch files for each group of 30 exe's and they run concurrently like they should.
I have created a "master" batch file that calls each sub-batch file but I can't figure out how to get it to run the sub-batch files in sequence, waiting for one to finish before starting the next.
If the master batch file is like this:
Batch1.bat
Batch2.bat
Batch3.bat
then only the first batch file is called - the others are never called.
If the master batch file is like this:
call Batch1.bat
call Batch2.bat
call Batch3.bat
then all of the sub-batch files start running at the same time and I get hundreds of executables trying to start up at the same time.
How do I make the master batch file call the first batch file, wait for it to finish, then call the next, wait for it to finish, then call the next, etc?
Thanks in advance,
rgames
When starting another batch CALL will start it in the same window and the called batch has access to the same variable context. So it can also change variables which affects the caller.
Using wait in your batch file to call the executable will wait for them to exit before.
START /WAIT batch1.bat
START /WAIT batch2.bat
Hope this helps
Excuse me. I think there is a misunderstanding here. If your master Batch file is this:
call Batch1.bat
call Batch2.bat
call Batch3.bat
then the Batch2.bat is called after Batch1.bat ends, and so on. You may do a small test to confirm this. On the other side, is possible that each BatchN.bat program uses the same variables? If so, then the last values left from Batch1.bat may interfere with Batch2.bat, and so on. In this case, you must add a Setlocal command at beginning of each Batch file.
I had to run a data export program for several files. My solution:
MasterBatch.bat:
#echo off
start /w batch1.bat
start /w batch2.bat
Batch1.bat
#echo off
cmd /c "c: & cd Program Files (x86)/PATH & targetProgram.exe -parametersToExportVideo1"
EXIT
Batch2.bat
#echo off
cmd /c "c: & cd Program Files (x86)/PATH & targetProgram.exe -parametersToExportVideo2"
EXIT
It may be adapted to run programs other problems.
You will have to create a signaling mechanism to aware EXE completation.
I would create a third level batch to run each EXE, creating a temp file before executing EXE and deleting it after.
In sub-batch I would wait until there were no more temp files.
So, initial batch:
call Batch1.bat
call Batch2.bat
call Batch3.bat
Sub-batch:
Set Index=0
Call :Exec exefile1 args ...
Call :Exec exefile2 args ...
...
:WaitAll
If Exist %Temp%\RUNNING_EXE.*.TMP GoTo :WaitAll
GoTo :EOF
:Exec
Set /A Index+=1
Echo %Index% > %Temp%\RUNNING_EXE.%Index%.TMP
Start Batch_3rd.BAT %*
GoTo :EOF
Finally, 3rd level batch, Batch_3rd.BAT:
%*
Del %Temp%\RUNNING_EXE.%Index%.TMP
%* are arguments passed from sub-batch (exe+arguments), %Index% is correct as start copies environment from sub-batch upon creation, and sub-batch don't change this copy.
One final note: you can probably merge all batches into a single batch file, calling it recursively.
My solution:
1)
I have four batch files:
Parent.bat and Batch1.bat, Batch2.bat, Batch3.bat
2)
Parent.bat contains the below lines (take a close note):
call Batch1.bat > result1.log
call Batch2.bat > result2.log
call Batch3.bat > result3.log
3)
Make sure "into the end of Each Child batch file", you have an echo statement.
After this echo statement there shouldn't be any code...
Say content of Batch1.bat file is:
echo begin
robocopy "C:\Users\DD\Documents\A" "C:\Users\DD\Documents\B"
echo end
echo this_is_the_last_line
Just for testing, i will use simple sub-batches like (all of them are the same)
#echo off
for /l %%a in (1 1 5) do start "" notepad.exe
And a master batch file
#echo off
setlocal enableextensions disabledelayedexpansion
set "flagFile=%temp%\%random%%random%%random%.tmp"
for %%a in ( "batch1.cmd" "batch2.cmd" "batch3.cmd" ) do (
call :startBatch %%a "%flagFile%"
)
:retryClean
echo %time% waiting for last batch to end
2>nul ( 9>"%flagFile%" break ) || ( >nul timeout 5 & goto :retryClean )
del /q "%flagFile%"
echo DONE
pause
goto :eof
:startBatch batchFile flagFile
echo %time% waiting to start "%~1"
2>nul ( 9>"%~2" call "%~1" ) || ( >nul timeout 5 & goto :startBatch )
echo %time% [ "%~1" ] STARTED
goto :eof
This code starts each of the sub-batches with an active redirection (user available stream 9 is used) to a temporary flag file. This will lock the flag file until all the processes started from sub-batches have ended as the redirection is inherited during the process creation.
All we have to do is to keep trying start the next batch file with the same redirection:
If the file is still locked (processes are running), the batch file can not be started, wait 5 seconds and retry again
If the file is not locked, the redirection can be created and the next batch file is started.
How to make .BAT file delete it self after completion? I have a simple bat file that terminates a process. I want that .BAT file to delete itself.
The Merlyn Morgan-Graham answer manages to delete the running batch script, but it generates the following error message: "The batch file cannot be found." This is not a problem if the console window closes when the script terminates, as the message will flash by so fast that no one will see it. But the error message is very undesirable if the console remains open after script termination.
John Faminella has the right idea that another process is needed to cleanly delete the batch file without error. Scheduling a task can work, but there is a simpler way: use START to launch a new delete process within the same console. It takes time for the process to initiate and execute, so the parent script has a chance to terminate cleanly before the delete happens.
start /b "" cmd /c del "%~f0"&exit /b
Update 2015-07-16
I've discovered another really slick way to have a batch script delete itself without generating any error message. The technique depends on a newly discovered behavior of GOTO (discovered by some Russians), described in English at http://www.dostips.com/forum/viewtopic.php?f=3&t=6491
In summary, (GOTO) 2>NUL behaves like EXIT /B, except it allows execution of concatenated commands in the context of the caller!
So all you need is
(goto) 2>nul & del "%~f0"
#ECHO OFF
SETLOCAL
SET someOtherProgram=SomeOtherProgram.exe
TASKKILL /IM "%someOtherProgram%"
ECHO "This script will now self-destruct. Please ignore the next error message"
DEL "%~f0"
Note that the DEL line better be the last thing you intend to execute inside the batch file, otherwise you're out of luck :)
This will print out an ugly error message, but it is benign, and the code is slightly less confusing this way. If you care a lot about getting rid of the error message, see dbenham's answer to get rid of it.
You didn't mention the OS, but if this is on Windows XP Professional and you have the appropriate permissions, you can have the batch file schedule a one-shot Windows Scheduled Task to delete the file at a later time. Use the schtasks command, documented here.
Otherwise, you typically can't delete a file that is being executed, since that has the potential for all sorts of nastiness. Additionally, trying to delete an executable in use is viewed as very suspicious behavior by any number of antivirus programs, so it's likely that you would run afoul of these as well.
Just add this command at the last line of your batch file
Del batch_file_name.bat
batch_file_name.bat is the name of your batch file
Cheers
you could do #Merlyn's aswer
#ECHO OFF
SETLOCAL
SET someOtherProgram=SomeOtherProgram.exe
TASKKILL /IM "%someOtherProgram%"
DEL "%~f0"
Now make a vbscript with this coding and save it as hidden.vbs, this vbscript will hide the batch file's window.
set w = CreateObject(“WScript.Shell”)
W.Run chr(34) & “%userprofile%\desktop\the_batch_file.bat” & chr(34), 0
set w= Nothing
Then have the batch file run this vbscript
#ECHO OFF
SETLOCAL
SET someOtherProgram=SomeOtherProgram.exe
TASKKILL /IM "%someOtherProgram%"
start "path to hidden.vbs"
DEL "%~f0"
This will hide the batch file before deleting it making the error message impossible to see.
Inline next command to do the "last things" as ghost self. It can be the exit command or some other things before exiting.
#echo off
del "%~f0" && echo All's done. I must exit! && pause > nul && exit
You could also direct the output of the DEL "%~f0" to NULL output like so...
#ECHO OFF
SETLOCAL
SET someOtherProgram=SomeOtherProgram.exe
TASKKILL /IM "%someOtherProgram%"
DEL "%~f0" > NUL