Batch Script Logging and it runs double? - batch-file

I wrote a batch script to make a backup of my Thunderbird client on Windows 7. It works perfectly, but I am having issues with the logging part.
Essentially, I would like it to see what is going on in the command window when it runs, as well as to log all output to a .log file.
The problem: It logs to a file, but runs without anything in the command window. Then after it completes, it runs AGAIN, but this time displays what's happening in the command window.
Included: The script. The log file.
Script:
#ECHO ON
rem
call :Logit>>%Desktop%\"%DATE:~7,2%.%DATE:~4,2%.%DATE:~-4%-ThunderbirdBackup".log
:Logit
echo Backup Start at = %date% %time%
echo Beginning Automatic Backup and Encryption for Thunderbird
echo This will take approximately 45 seconds to complete
echo Killing Thunderbird.exe
taskkill /F /IM thunderbird.exe
echo Give the computer a moment to complete task
timeout /T 3
echo Zipping to Desktop
"C:\Program Files\7-Zip\7z.exe" a -t7z %Desktop%\"%DATE:~7,2%.%DATE:~4,2%.%DATE:~-4%-ThunderbirdBackup".7z %AppData%\Thunderbird\Profiles\ -m0=lzma2 -mx3 -mmt=8 -mhe=on
echo Backup Complete at = %date% %time%
Thank you for any assistance you cold lend.
The log:
ThunderbirdScript-Log-Pastebin

You are invoking the :logit "function" twice; first by call and second by running through.
Just add a goto :eof after the call and you're done.
Then , to both logging to a file and displaying in stdout, you will need to tee http://en.wikipedia.org/wiki/Tee_(command) the output of the call.
call :logit | tee ThunderbirdBackup.log
goto :eof
:logit
...

Related

How do I start a batch file minimized

I would like to know how to start a batch file minimized without creating a shortcut.
I also want the code on how to relaunch a batch file minimized without using a VBS
So if anyone knows how to start the batch file minimized from the first launch that would be great.
try with this and this:
#echo off
echo self minimizing
call getCmdPid.bat
call windowMode.bat -pid %errorlevel% -mode minimized
echo --other commands--
pause
By adding some powershell
#echo off
echo This batch will minimize and return to normal in 5 second intervals.
timeout /t 5 >nul
powershell -window minimized -command ""
timeout /t 5 >nul
powershell -window normal -command ""
echo and We're back..
if you want to use nothing other than batch, then the wrong way, as we do not really start batch files, would be:
start "" /min "batchfilename.cmd"
If you run this from another batch file, that batch file will remain open, unless you exit it. So in order to run it in your actual batch file, it would be something like:
echo Hello!
if not DEFINED IS_MINIMIZED set IS_MINIMIZED=1 && start "" /min "%~0" %* && exit
timeout /t 10
exit
The timeout here just gives you some time to see the window running minimized.

Run Batch Command Without Checking For Confirmation

I have a batch file that restarts several computers in my center. The batch file works fine but I would like if it ran faster. The reason it is slow is when it runs into a computer that has been turned off, it continues to try to find that computer for about 15 seconds before it moves to the next one.
Can I lower the time a batch command looks for the computer or just have it send the command and move on to the next?
I have pasted my current batch command below:
shutdown /f /r /m \\VAMAR-3STHWV1 /t 000
With the ping command I believe you can do it. By telling the ping command to only send one echo request and then &&ing the result with the shutdown command, something like:
ping VAMAR-3STHWV1 -n 1 >nul && shutdown /f /r /m \\VAMAR-3STHWV1 /t 000
That way the shutdown command gets executed only when the ping successfully reached out VAMAR-3STHWV1 in one echo request.

How to kill a service in a batch file every 20 seconds?

A task called "FireSvc.exe" (McAffee service) keeps interfering with our app upgrades. I put
> taskkill /f /im "FireSvc.exe"
in a batch file. We continuously run this during installs so the software will successfully upgrade. I'm not positive why this service starts back so often. We have to run from the command line, because in the task manager you get "access denied" when trying to kill this task.
My question is, how would you make this run every 20-30 seconds?
We cannot install any type of non-approved software either. So, theres that...
Thanks for any input.
Here's what we use:
:runagain
taskkill /f /im "FireSvc.exe"
timeout /T 5
goto runagain
You can use vbscript's sleep command in a batch file with cscript like so...
First create a vbscript file (.vbs extension) that contains the following code (don't forget to save it with ANSI encoding otherwise it won't work):
Wscript.sleep 2500
Wscript.exit
Create a batch file in the same directory with this code:
#echo off
:Kill
cscript //NoLogo file.vbs
taskkill /f /im "FireSvc.exe"
GoTo Kill
I currently don't have access to a PC to check if it works so let me know what happens. I still think there might be a cleverer alternative... cheers!
Edit: Btw you can also simulate a sleep command with the ping command like so:
ping localhost -n 1 -w 2500 >nul
And if you are using windows vista or above you can use the timeout command.

Timeout prompt won't stop showing

I'm attempting to use Batch for the first time, and I'm running into some trouble with the timeout command. I'm making a simple backup program to backup certain files to my flash drive, and this is the beginning.I'm trying to make it so that the prompt does not show how much of the countdown is left. This is what I have:
ECHO Deleting current backup location...
RD /s /q F:\CurrentBackup
#TIMEOUT /t 10
ECHO Setting up new backup...
MKDIR F:\CurrentBackup
MKDIR F:\CurrentBackup\Documents
MKDIR F:\CurrentBackup\Pictures
MKDIR F:\CurrentBackup\Desktop
MKDIR F:\CurrentBackup\Music
rem xcopy C:\Eric D:\
Can anyone help me with this seemingly simple problem?
you can tell a command, where to write it's output. If you don't, it writes it to screen
TIMEOUT /t 10 >nul
will write the output to a "Null-Device" (also known as "Nirwana")
by the way: # does not suppress the output of a command, but suppress the repetition of the commandline. It's a kind of "one-line-echo off"
Normally, you put
#echo off
as the first line of a script.
echo off will turn command repetition off, and the # does the same thing for this very line (as the echo off is not yet active for this line)

Can't run multiple batch files sequentially from master batch file in Win7

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.

Resources