BATCH - wait for file to be complete before picking up - batch-file

I have a command that watches a certain folder for new files. These files are created by a video transcoder so are locked and keep growing in size till completion.
#echo OFF
:loop
if exist "E:\OUT\*.mxf" (
for %%i in ("E:\OUT\*.mxf") DO (
C:\bmx\bmxtranswrap -o "E:\DPP_create\DPP_OUT\%%~ni.mxf" -t as11op1a -y 09:59:50:00 --afd 10 "%%i"
ping -n 5 localhost >nul
del "%%i"
)
)
ping -n 5 localhost >nul
goto :loop
Is there a way to only pick up files which are fully completed (Windows unlocked)? At the moment the next command is tripping up as it is attempting to open an incomplete file.
Any advise? Thanks.

As long as you are correct in that your transcoder has the file locked until it is complete, then the solution is actually simple.
Use redirection to test that you can open the file for writing, but don't modify it. Only process if the redirection succeeded.
Note:
You don't need your outer IF statement.
You can use an infinite FOR /L loop instead of a GOTO loop
I don't understand why you need a delay before your DEL, but I preserved it anyway.
#echo OFF
for /l %. in () do (
for %%i in ("E:\OUT\*.mxf") do 2>nul( (call )>>"%%i" ) && (
C:\bmx\bmxtranswrap -o "E:\DPP_create\DPP_OUT\%%~ni.mxf" -t as11op1a -y 09:59:50:00 --afd 10 "%%i"
ping -n 5 localhost >nul
del "%%i"
)
ping -n 5 localhost >nul
)

Related

Store curl command output in a variable in batch script

I tried many examples online, but was not able to make it work. I am new to this so please forgive my primitive question.
say I have this:
curl "www.google.com" -o /dev/null -s -w "%{http_code}\n"
when running this in a cmd window, it returns the response code.
200
which is as expected.
I would like to do something like this in a batch script, but also use the output of the curl command to set a variable.
All examples I found online propose:
set res = $(curl "www.google.com" -o /dev/null -s -w "%{http_code}\n")
echo %res%
pause
or like this
FOR /F "tokens=* USEBACKQ" %%F IN (`curl www.google.com -o /dev/null -s -w "%{http_code}\n"`) DO ( SET var=%%F )
ECHO %var%
pause
both did not work, my batch script closes immediately.
Any feedback or help is highly appreciated
thank you.
Thanks to #Compo, here is the formatted answer for other's benefit.
#echo off
For /F %%G In ('%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}\n"') Do Set "response=%%G"
echo response code is %response%
IF %response% == 200 (
ECHO was able to ping google
) ELSE (
ECHO unable to ping google
)
pause
As he has mentionned above #Compo in his comment :
"To get the result of the command as a variable at the Command Prompt, you'd use For /F"
#echo off
Title Store curl command output in a variable in batch script
Set "MyCommand=curl "www.google.com" -o NUL -s -w "%%{http_code}""
#for /f %%R in ('%MyCommand%') do ( Set VAR=%%R )
echo %VAR%
pause
Based upon your own answer code, there's no need to use a for-loop to get the result saved to a variable, and then compare that variable value with a known value. You can pipe the result through findstr to see if it matches your known value instead.
Example batch-file:
#%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}" ^
| %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded
) || Echo Ping Failed
#Pause
It is only really one line, split for readability, so you could do it line this in cmd:
%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%{http_code}" | %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded) || Echo Ping Failed
Or like this as a batch-file:
#(%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}" | %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded) || Echo Ping Failed) & Pause
Other answers are good, but I would not use CURL to just test if we can reach a site:
#echo off
ping google.com -n 1 >nul 2>&1
if %errorlevel% equ 1 (
echo EHHH..NO Google is not down, we are
) else (
echo HURRAH MAN We are OK
)

Set filename as variable in BATCH

Am new to this so hope someone can assist a novice. Cannot locate the answer so far. Essentially I am trying to create a watch folder which picks up new .MXF files, runs a specific command line application and renames the new file with the original filename plus _new.
#echo off
:loop
if exist "C:\Input\*.mxf" (
for %%a in ("C:\Input\*.mxf") do (
C:\BMX\bmxtranswrap -o C:\Output\NEW.mxf -t as11op1a -y 09:59:50:00 --afd 10 --pass-anc all -anc-max 2048 "%%a"
ping -n 5 localhost >nul
del "%%a"
)
)
ping -n 5 localhost >nul
goto :loop
I originally tried using %~n1 command to pass through the name which works in a CMD script I have.
C:\BMX\bmxtranswrap -o C:\Output\%~n1_NEW.mxf -t as11op1a -y 09:59:50:00 --afd 10 --pass-anc all -anc-max 2048 "%%a"
This doesn't work however. If there is a command I am missing to pass through the source filename then please let me know.
Many thanks.
You need to extract the filename without the extension in order to use it as a variable in the new name.
To get the filename you can use:
%%~ni
This should work:
#echo off
if exist "C:\Input\*.mxf" (
FOR %%i IN ("c:\Input\*.mxf") DO (
REM ECHO %%~ni - This is the filename without the extensoion for the new file
C:\BMX\bmxtranswrap -o C:\Output\%%~ni_new.mxf -t as11op1a -y 09:59:50:00 --afd 10 --pass-anc all -anc-max 2048 %%i
ping -n 5 localhost >nul
del %%i
)
)
NOTE:
I've tested the above code without the bmxtranswrap line and the new filenames were displayed as expected: test_new.mxf and test2_new.mxf

My Batch file wont continue while windows is locked

I have a batch file which calls other programs to open and run.
I want this batch file to run overnight while my computer is locked. I use Windows Task Scheduler to run this program overnight. The batch file runs fine except when it gets to start Check1.msl. Then windows can't seem to find that file. When I unlock my computer and manually execute the batch file, it has no problem finding and running those files.
Here is my code:
#echo off
Start Check1.msl
PING 1.1.1.1 -w 1000 -n 1
start passwordinjector.vbs
IF EXIST C:\Users\Username\Desktop\New folder\check.rpt (
taskkill /IM MAINRDW.exe >nul
PING 1.1.1.1 -w 500 -n 1
Start Trial.msl
PING 1.1.1.1 -w 1000 -n 1
start passwordinjector.vbs
Del C:\Users\Username\Desktop\New folder\check.rpt
) ELSE (
PING 1.1.1.1 -w 500 -n 1
taskkill /IM MAINRDW.exe >nul
)
EDIT:
I've been trying it out for awhile now. To test it, I simply use Windows Task Scheduler to run it a minute out then lock my computer and wait for the Scheduler to kick in.
Here is what I have so far:
#echo off
cd /d "%~dp0"
PING 1.1.1.1 -w 2000 -n 1
echo starting the check1 msl file
Start Check1.msl
PING 1.1.1.1 -w 2000 -n 1
echo starting the password injector file
WScript //B passwordinjector.vbs
IF EXIST C:\Users\USERNAME\Desktop\New folder\check.rpt (
echo check if the check exists
taskkill /IM MAINRDW.exe /f >nul 2>&1
PING 1.1.1.1 -w 2000 -n 1
echo It does exist, so run the next Trial msl
Start Trial.msl
PING 1.1.1.1 -w 3000 -n 1
WScript //B passwordinjector.vbs
Del C:\Users\USERNAME\Desktop\New folder\check.rpt
) ELSE (
PING 1.1.1.1 -w 1000 -n 1
it doesnt exits
taskkill /IM MAINRDW.exe /f >nul 2>&1
)
exit
It is very hard to troubleshoot batch files. If anyone has any suggestions, I would appreciate it. Through trial and error, I figured out (still not sure) that it wasn't executing the .vbs script. So I looked it up online from Microsoft's developer network and got the syntax WScript //B.
EDIT2:
I put a pause into the code to break it down and make sure it is doing what it is supposed to do. Its not.
The Check1.msl will spit out a file named check.rpt. When i run it manually and the batch file pauses - check.rpt is there. I schedule the task and lock my computer. When I log back in, the msl program is open and the cmd prompt is sitting at pause but there is NO check.rpt file.
Here is what I have at the beginning:
#ECHO OFF
PUSHD "%~dp0
ECHO CD is now %CD%
PING 1.1.1.1 -w 2000 -n 1
echo starting the check1 msl file
DIR Check1.msl
Start Check1.msl
PING 1.1.1.1 -w 2000 -n 1
echo starting the password injector file
WScript //B passwordinjector.vbs
pause
I've tried cscript passwordinjector.vbs to no avail.
The .bat script can make the current working directory to be the one in which it is located by:
PUSHD "%~dp0"
Remember to POPD before exiting.
#ECHO OFF
PUSHD "%~dp0"
ECHO CD is now %CD%
DIR Check1.msl
START Check1.msl
...
It seems like the issue lies in the VBScript. I use .sendkey to inject the password. This is retricted while the computer is locked; so I'm out of luck.

Using a .bat to extract text between two words

I have a media server and I'm attempting to automate ripping my collection of movies and any future movies using MakeMKV. Ripping and moving is working without a hitch. The problem I'm running into is occasionally MakeMKV doesn't assign a title to the MKVs and I end up with title00.mkv which Media Center Master obviously cannot even begin to try to match to any metadata.
MakeMKV does offer the ability to get the information from the disc which I have print to info.txt which looks like this.
MSG:1005,0,1,"MakeMKV v1.8.10 win(x64-release) started","%1 started","MakeMKV v1.8.10 win(x64-release)"
DRV:0,2,999,1,"HD-DVD-ROM HL-DT-ST BD-RE GGW-H20L YL05","FARFROMHOME_16X9","\\Device\\CdRom0"
DRV:1,256,999,0,"","",""
DRV:2,256,999,0,"","",""
DRV:3,256,999,0,"","",""
DRV:4,256,999,0,"","",""
DRV:5,256,999,0,"","",""
DRV:6,256,999,0,"","",""
DRV:7,256,999,0,"","",""
DRV:8,256,999,0,"","",""
DRV:9,256,999,0,"","",""
DRV:10,256,999,0,"","",""
DRV:11,256,999,0,"","",""
DRV:12,256,999,0,"","",""
DRV:13,256,999,0,"","",""
DRV:14,256,999,0,"","",""
DRV:15,256,999,0,"","",""
FARFROMHOME_16X9 is the label for the disc.
How can I extract this and rename my .mkv when makemkv has finished?
Here is my BAT so far (my first attempt at a .bat):
makemkvcon64 -r info disc > info.txt
makemkvcon64 --minlength=3600 mkv disc:0 all C:\Users\HTPC\MakeMKV_Temp\
START /WAIT makemkvcon64.exe
cd "c:\Program Files (x86)\FreeEject\"
FreeEject d:
move C:\Users\HTPC\MakeMKV_Temp\*.mkv C:\Users\HTPC\Movies\
Renaming the file before the move would be ideal.
Although you posted an ample description of your problem and data, you have not explained what exactly you want as result, so I must guess a couple points. The lines below extract the sixth comma-separated token from the second line of info.txt file:
for /F "skip=1 tokens=6 delims=," %%a in (info.txt) do set "discLabel=%%~a" & goto continue
:continue
echo The label of the disk is: %discLabel%
This is the output of previous lines when they are executed on your example data:
The label of the disk is: FARFROMHOME_16X9
You also have not indicated the name of the file you want to rename (before move it). Below is a possible solution to your problem that should be adjusted when previous unclear points be defined:
makemkvcon64 -r info disc > info.txt
for /F "skip=1 tokens=6 delims=," %%a in (info.txt) do set "discLabel=%%~a" & goto continue
:continue
makemkvcon64 --minlength=3600 mkv disc:0 all C:\Users\HTPC1\MakeMKV_Temp\
START /WAIT makemkvcon64.exe
cd "c:\Program Files (x86)\FreeEject\"
FreeEject d:
ren C:\Users\HTPC1\MakeMKV_Temp\TheNameHere.mkv %discLabel%.mkv
move C:\Users\HTPC1\MakeMKV_Temp\*.mkv C:\Users\HTPC1\Movies\
I've been wrangling with the same thing and created something that works fairly well.
MakeMKV uses it's own output FileName like you indicated "title00.mkv" or something similar.
I've created two(2) batch files to perform my home movie automation.
The first is "RipWorkflow_DVD.bat", which handles all the heavy lifting to call MakeMKV first to rip the content to my drive. Also in this file is a call to Handbrake to convert the MKV to MP4 (my stupid "smart" tv won't play MKV, but likes MP4)
The second batch file "OneStepDVDRip.bat" calls the first, but with parameters I choose for
a) location of the MKV
b) the output name of my MP4
c) the minLength of a track to locate and rip to MKV
Here is the code for "OneStepDVDRip.bat"
call "C:\Users\Todd\Desktop\RipWorkflow_DVD.bat" "Z:\Video\TrueStory" "E:\My Videos\Movies\Drama\True Story (2015).mp4" 3600
Here is the code for "RipWorkflow_DVD.bat"
#echo off
cls
setlocal ENABLEDELAYEDEXPANSION
SET input=%1
SET output=%2
SET minlength=%3
echo
echo %input%
echo %output%
echo
if not exist %input% ( mkdir "%input%" )
call "C:\Program Files (x86)\MakeMKV\makemkvcon64.exe" --minlength=%minlength% --decrypt mkv disc:0 0 "%input%
timeout /t 5 /nobreak
for %%F in (%input%\*.mkv) do (
echo %%~dpnxF
echo %output%
call "C:\Program Files\Handbrake\HandbrakeCLI.exe" -v1 -i %%~dpnxF --main-feature -o %output% -f mp4 --markers -e x264 -b 2000 -a 1 -E faac -6 dpl2 -R 44.1 -B 128 -D 1.75 --subtitle-forced -x ref=2:bframes=2:subme=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0
timeout /t 5 /nobreak
DEL %%F /Q
)
endlocal

How do I skip a computer in a batch file that is unreachable?

#echo off
:begin
for /f %%a in (computerlist.txt) do (
setlocal
psexec \\%%a -u user -p password -i -d "d:\path\command.exe"
endlocal
)
when the script is running, when it finds a machine to be unreachable I want it to skip it.
How do i write the script to skip an unreachable computer and continue to the next one in the txt file?
How about a simple test to see whether a machine is pingable?
#echo off
setlocal
:begin
for /f %%a in (computerlist.txt) do (
ping -n 1 %%a >NUL 2>NUL
if %errorlevel%==0 (
psexec \\%%a -u user -p password -i -d "d:\path\command.exe"
) else echo Skipping unreachable host %%a
)
endlocal
Actually, windows ping.exe doesn't return meaningful errorlevels, (huh?)
It ALWAYS returns a "0" errorlevel, unless the IP-Protocol stack itself is hosed.
WHAT YOU HAVE TO DO IS: pipe the output of your ping to a txt-file, and "find" for TTL=
ie
ping 10.10.10.10. >pingtest.txt
findstr /C:"TTL=" pingtest.txt >nul
if %ERRORLEVEL% equ 0 (do whatever) else (echo skipping unreachable host "whatever")
Then use Find.exe or Findstr.exe to look for TTL= in your output file
(note find, and findstr both use "0" errorlevel when they "find" what your searched on)
1. Ping can fail for a whole lot of reasons, but "TTL=" is always part of a successful ping
2. I always ping at least -n 3 times, because occasionally the first one or two might have problems, and I want to give it more possible chances to succeed before I skip it.
3. For this to work, you have to use the FOR loop method above, just raw psexec.exe has not current means to test/skip targets called from a text file.
4. If you need to use network resource in your psexec session then you need to run the "-h" option so that you get the elevated token, which allows you to map drives
I HOPE THIS HELPS !

Resources