Batch script Mix Forfiles Cmd to print a PDF - batch-file

I'm stuck with this script
echo off
SET pathAdobe="C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
SET pathDestination=T:\
cd %pathDestination%
(1)
forfiles /P %pathDestination% /M *8.pdf /D +0 /C "cmd /c echo #PATH"
(2)
"C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" /o /h /s /t "%pathDestination%\pdf8.pdf" "MyPrinterName"
pause
(1) Work fine, i got a list of pdf according my forfiles
(2) Work fine, print my file
(3) But when i want to mix the 2 first step that doesn't work like i want
forfiles /P %pathDestination% /M *8.pdf /D +0 /C "CMD /C "%pathAdobe%" /o /h /s /t #PATH"
I got this error:
Error: Invalid argument or option - « Files\Adobe\Acrobat »
I try to escape with ^ " \ but don't change the result
Can't find a solution!
Thanks for any help you can give me :)
J

Your issue is that you are including double quotes, in the wrong places, and that those double quotes require escaping. You can escape those using backward slashes (\"), or by using their hexadecimal character code, (0x22).
Backward slash example:
#Echo Off
Set "pathAdobe=%ProgramFiles%\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
Set "pathDestination=T:\"
CD /D "%pathDestination%" 2> NUL || Exit /B
%SystemRoot%\System32\forfiles.exe /M "*8.pdf" /D 0 /C "%SystemRoot%\System32\cmd.exe /D /C \"\"%pathAdobe%\" /o /h /s /t #Path \"MyPrinterName\"\""
Pause
Hexadecimal character example:
#Echo Off
Set "pathAdobe=%ProgramFiles%\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
Set "pathDestination=T:\"
CD /D "%pathDestination%" 2> NUL || Exit /B
%SystemRoot%\System32\forfiles.exe /M "*8.pdf" /D 0 /C "%SystemRoot%\System32\cmd.exe /D /C 0x220x22%pathAdobe%0x22 /o /h /s /t #Path 0x22MyPrinterName0x220x22"
Pause

Related

Get list of empty folders older then x days

I need to get a list of empty folders in a given location, older then x days. Using "forfiles" I'm able to get all older folders, but not the empty ones. Using "for" I'm able to get all empty folders, but I can't seem to set the older ones.
Get empty folders:
#for /r "c:\FileStore" /d %F in (.) do #(dir /b "%F" | findstr "^" >nul || echo %~fF)
Get older folders:
ForFiles /p "C:\FileStore" /s /d -3 /c "cmd /c if #isdir==TRUE echo #path"
How do I combine these 2 commands?
You need to escape the quotation marks of the part findstr "^" for forfiles. There is the way \", but I do not recommend this, because the " are still recognised by the command interpreter cmd (user Ben Personick shows how to do this in his answer though). Anyway, I would use 0x22 instead in order to hide the quotes from cmd, like this:
forfiles /S /P "C:\FileStore" /D -3 /C "cmd /C if #ISDIR == TRUE (dir /B /A #PATH | findstr 0x22^0x22 > nul || echo #PATH)"
Instead of findstr "^" you could also use find /V "":
forfiles /S /P "C:\FileStore" /D -3 /C "cmd /C if #ISDIR == TRUE (dir /B /A #PATH | find /V 0x220x22 > nul || echo #PATH)"
But the easiest way is to use set /P:
forfiles /S /P "C:\FileStore" /D -3 /C "cmd /C if #ISDIR == TRUE (dir /B /A #PATH | set /P _= || echo #PATH)"
N. B.:
forfiles only regards the date (not the time) of the last modification, but not the creation date/time.
Your biggest hurdle is escaping the double quotes in the FindStr and the Carrot needing doubling too (or it will stop the following quote from being escaped.)
Hmm strange I thought you asked to delete these directories, since you haven't I'll amend it as such.
ForFiles /P "c:\FileStore" /d -3 /C "CMD /C if #isdir==TRUE ( DIR /B #Path | FindStr \"^^\" >NUL || ECHO Empty Folder: #Path )"
Also since you are only looking for a list of those it does make sense to kill the output from the FindStr so I added the >Nul back in.
Again not sure how I ot it into my head that you wanted to remove the empty folders older than 3 days old, since there isn't such a requirement, the portion about needing to re-run the command is moot and I've remove dit for now.

Batch file to "echo" files older than 7 days

I have tried the following command:
forfiles /P "C:\test\" /S /M *.* /D -7 /C "cmd /c echo #path"
but it returns an error:
screenshot here
I'm not sure what's wrong, the syntax should be fine.
Remove the last backslash in your search path : "c:\test" instead of "c:\test\"
So it should be :
forfiles /P "C:\test" /S /M *.* /D 7 /C "cmd /c echo #path"
/D 7 is "seven days in the future". Unlikely you have such files (except you own one of those awesome time travel machines).
forfiles /P "C:\test\" /S /M *.* /D -7 /C "cmd /c echo #path"

Assign command return value in batch file

I am using the below to count the files number which created days is older than 10 days:
forfiles /m *.txt /d -10 /c "cmd /c echo #path" | find /c /v "" >count.tmp
for /f %%b in (count.tmp) do #set /a count=%%b
is there anyway that can assign return value without save a file?
for /f %%b in ('forfiles /m *.txt /d -10 /c "cmd /c echo #path" ^| find /c /v "" ') do set /a count=%%b
should assign count to the value output from forfiles.
See for/? from the prompt for documentation. The caret before the pipe is an escape character to inform cmd that the pipe is part of the command to be executed.

How to get ERRORLEVEL of a command in forfiles?

I need to handle files older than a day. Thereforw I use this:
forfiles -m %%~nxf /C "cmd /c start /wait /MIN 7z.exe t %%f" /d +1
Now I'd like to check if the progress of 7z.exe succeeded. How can I get the errorlevel of the command inside the forefiles command? Is there any possibility?
I already tried following ways which did not work. errorlevel always returns 0, even if I use broken files, that should return an error (2).
forfiles -m %%~nxf /C "cmd /c start /wait /MIN 7z.exe t %%f && echo ok || echo delete %%f" /d +1
forfiles -m %%~nxf /C "cmd /c start /wait /MIN 7z.exe t %%f && if errorlevel 2 (DEL %%f)" /d +1
Assuming 7z.exe does really deliver an ErrorLevel, I think that the conditional command separators query the ErrorLevel of cmd rather than of 7z.exe. The following should work:
forfiles /M "%%~nxf" /C "cmd /C 0x22start /WAIT /MIN 7z.exe t 0x22%%~f0x22 && echo ok || echo delete 0x22%%~f0x220x22" /D +1
Or you can do that also without start:
forfiles /M "%%~nxf" /C "cmd /C 0x227z.exe t 0x22%%~f0x22 && echo ok || echo delete 0x22%%~f0x220x22" /D +1
As you might have noticed, I also fixed some quote issues for the given paths.

Batch file (ForFiles multiple conditional commands for logic)?

I am just getting into Bat files.
I am trying to delete old folders on a network shared drive but skip 2 of the containing folders by name.
Basically I need to all files that I make daily and always keep 2 old files.
Code that deletes all files that are older than 3 days:
PushD "\\****-****\build" &&(
ForFiles /D -3 /C "CMD /C if #ISDIR==TRUE echo RD #FILE &RD /S #FILE
) & PopD
And I was thinking something like this: if NOT #FNAME == %name%. I don't totally understand the process, am I able to have two conditions in the forFiles? do I have to have /c before?
PushD "\\****-****\build" &&(
ForFiles /D -3 /C "CMD /C if NOT #FNAME == %name% if #ISDIR==TRUE echo RD #FILE &RD /S #FILE
) & PopD
I can't seem to get it, would you mind helping me out?
Thanks!
Yes, nesting if commands in their then branches is the way how-to have logical AND. Note proper quoting in next code snippet:
#ECHO ON >NUL
#SETLOCAL enableextensions
set "name=SO"
set "nam2=SU"
pushd "D:\VB_scripts"
#rem all directories
ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE echo #FILE"
#rem all directories except "SO"
ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE if not #FNAME=="""%name%""" echo #FILE"
#rem all directories except "SO" and "SU"
ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE if not #FNAME=="""%name%""" if not #FNAME=="""%nam2%""" echo #FILE"
popd
#ENDLOCAL
Output:
==>D:\bat\SO\31346676.bat
==>set "name=SO"
==>set "nam2=SU"
==>pushd "D:\VB_scripts"
==>ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE echo #FILE"
"Class Pack"
"Oldies"
"SO"
"SU"
"WMI"
==>ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE if not #FNAME=="""SO""" echo #FILE"
"Class Pack"
"Oldies"
"SU"
"WMI"
==>ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE if not #FNAME=="""SO""" if not #FNAME=="
""SU""" echo #FILE"
"Class Pack"
"Oldies"
"WMI"
==>popd
It is a little bit messy but I was able to do it on a local directory:
#echo off
mkdir Temp\Temp
REM Copy all old file to Temp dir
forfiles -p "%cd%" -m *.* /D -2 /C "cmd /c xcopy #path %cd%\Temp"
REM copy a random file from Temp dir to Temp/Temp dir and then delete it
FOR %%A in (%cd%\Temp\*) do (
COPY "%%A" %cd%\Temp\Temp\
DEL "%%A"
GOTO :Second
)
:Second
Rem copy second random file from Temp dir
FOR %%A in (%cd%\Temp\*) do (
COPY "%%A" %cd%\Temp\Temp\
GOTO :Del
)
:Del
Rem delete all old files from local dir
forfiles -p "%cd%" -m *.* /D -2 /C "cmd /c del #path"
Rem Copy back two random old files to local dir
xcopy %cd%\Temp\Temp\* %cd%
Rem remove Temp dir
rmdir /s /q Temp

Resources