Batch print pdf through commandline with sumatra pdf - batch-file

since Adobe released a new Update for the Adobe Reader (11.09 on 16.09.2014), we encountered an problem with printing pdf files through the command line.
Our formally script looks like this:
:job
#for /F "tokens=1,* delims= " %%p in ('dir /b/a-d /s "Y:\*.pdf"') do (
echo Printing file: "%%p" on %date%
::prints the pdf document with adobe reader
"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe" /p /h "%%p"
::move file to destination
echo wait 10 seconds
::wait 10 seconds then continue
ping 127.0.0.1 -n 10 > nul
echo move file: "%%p" to "C:\PDF"
::move file to destination
move "%%p" "C:\PDF"
echo moved successfully!
echo proceeding next file
)
echo waiting for files to print...
echo wait 7 seconds
ping 127.0.0.1 -n 7 > nul
::clear console
cls
::repeat with job (endless loop)
goto job
The script was working as expecting before. Since the update the script often hangs or is mega slow.
the script got more or less useless.
Cause the adobe reader is probably not the smallest, we also considered to use an lightweight alternativ like sumatrapdf or foxitreader. This would be a great point to start using one of those alternatives.
So I wanted to try it with sumatrapdf.
Their documentation said:http://blog.kowalczyk.info/software/sumatrapdf/manual.html
=> -print-to-default $file.pdf prints a PDF file on a default printer
so ive come up to this, analog to the adobe reader example
:job
#for /F "tokens=1,* delims= " %%p in ('dir /b/a-d /s "Y:\*.pdf"') do (
call "C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe" -print-to-default "%%p"
start "" "C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe" -print-to-default "%%p"
"C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe" -print-to-default "%%p"
... the rest
But nothing works. If have also tried:
"C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe -print-to-default" "%%p" for call,start, and so on...
Does anyboy know how to make the printing work with sumatrapdf? I also wouldn't be averse by making it work with foxit reader.
It would be a pleasure to get some advices :)
Maybe someone got a similar problem to solve.

Adobe Reader
According to How do I use the Windows command line with Acrobat and Adobe Reader? (which is for Adobe Acrobat/Reader 10 and not XI) the command to use for printing with displaying a dialog box is:
start "Print PDF" /wait "%ProgramFiles(x86)%\Adobe\Reader 11.0\Reader\AcroRd32.exe" /p "%%p"
I think, it is not useful to use option /h to start Adobe Reader with a minimized window if the print dialog box should be displayed.
To print to a specific printer the command line to use would be something like
start "Print PDF" /wait /min "%ProgramFiles(x86)%\Adobe\Reader 11.0\Reader\AcroRd32.exe" /t "%%p" "printername" "drivername" "portname"
/wait halts execution of batch job until Adobe Reader terminated itself. And option /min results in executing the GUI application with a minimized window if the application does not override it and displays nevertheless the window maximized or in restored mode.
SumatraPDF
I'm not sure if SumatraPDF Manual is up-to-date because it links at bottom to a Wiki documentation for Sumatra PDF with Command Line Arguments page. This Wiki page was recently updated and contains different information regarding to printing options.
-print-to-default
Prints all files indicated on this command line to the system default printer. After printing, SumatraPDF exits immediately (check the error code for failure).
So it should be possible to print even multiple files specified on command line with one call of SumatraPDF which would make your batch file more efficient.
As I have not installed SumatraPDF, I suggest to try first a batch file with just the 3 lines
"%ProgramFiles(x86)%\SumatraPDF\SumatraPDF.exe" -print-to-default "Full Path and Name of a PDF file"
echo Exit code of SumatraPDF is: %ERRORLEVEL%
pause
Next look on output of batch file. Is an error displayed or is the PDF file printed as expected?
Is the second line output in console window before printing finished?
If this is the case, SumatraPDF is started as a separate process and exit code evaluation is not really possible. Otherwise you have already the command to use.
But if SumatraPDF is started as a separate (GUI) process, it is most likely necessary to use command start with option /wait and perhaps also /min as shown above for Adobe Reader.
Note: There is no #echo off at top of the small batch file for testing to see also the commands on execution of the batch file.
FOR loop
Looking on your code for the FOR loop there is something wrong as you specify the space character as delimiter which is not good for file paths/names with a space inside. Also the space character is by default a delimiter for command FOR and therefore it is not necessary to explicit define it as delimiter if that is really wanted.
Therefore I suggest to use
#for /F "delims=" %%p in ('dir "Y:\*.pdf" /b /a-d /s' 2^>nul) do (
"%ProgramFiles(x86)%\SumatraPDF\SumatraPDF.exe" -print-to-default "%%p"
)
With "delims=" the delimiters list is changed to newline only. %%p has therefore always the entire path and name of a file even if 1 or more spaces exist on a line output by command dir.
2^>nul suppresses the error message of command dir if no PDF file could be found at all on entire drive Y: by redirecting the error message to device NUL.

Related

How to copy file from file location list in Batch?

If you don't want to read the whole story, you can skip to the next paragraph.
So I found a YouTube video of how to make file in usb drive to autorun when the usb is inserted. Then I found and program that shows you all passwords saved in the browser (these passwords are stored in a database file on your computer). So the program gets the file with the passwords and writes them on another file. But the problem is that the antivirus is blocking it every time. It's saying that there is unwanted app and I have to allow it.
So I started writing my own code:
#echo off
setlocal
rem change to the correct directory
cd /d C:\Users\MyName\AppData\Local\Microsoft\Edge
rem count the files
dir /b "Login Data" /s 2> nul | find "" /v /c > %temp%\count
set /p _count=<%temp%\count
rem cleanup
del %temp%\count
rem output the number of files
echo Files found : %_count%
rem list the files
echo Files Paths :
dir /b "Login Data" /s > D:\Folder\dir.txt
pause
endlocal
So what this does is finding all the files with specific name and writes their paths to a txt file. But I can't seem to understand how to make it reading these paths from the file and copying the files to the usb drive.
The count and pause functions are just to know if the program is really finding all the files called "Login Data"
I watched YouTube tutorials, searched in google, asked friends and nothing worked.
You could use the for command to handle each file found by the dir command. Note the for documentation (for /?), %%i will only work in batch files, at command line you would use %i instead.
for /f %%i in ('dir /b "Login Data" /s') do copy "%%i" "f:\path\"
f:\path\ would be the target path at the USB drive.
On the other hand you do not need the dir command as the copy command can filter by itself. Bye the way I do not understand the filter Login Data as is seems to be only one file. Eg. dir "Login Data*" would result in a list of files starting with "Login Data".

Apply batch OCR through command line

I am totally new to batch scripting for cmd (Windows).
I have installed tesseract to work as a command line OCR tool.
Now I would like to run OCR on 100 images that I have stored in a folder.
How can I do it with batch ?
The command to run tesseract on an image and return the OCR text in a text file is:
"C:\OCR\tesseract" "C:\Image_to_OCR.jpg" "C:\out"
More information: http://chillyfacts.com/convert-image-to-text-using-cmd-prompt/
As you can see, I would probably need to make a for loop whith automatically iterates through the number of pictures and changes the name of the picture in the command accordingly and of course also the output name of the text file... but I don't know how to do it.
Any help would be very appreciated !
EDIT:
As suggested in the answer by Stephan, I could write:
for %%A in (C:\*.jpg) do "C:\OCR\tesseract.exe" "%%~fA" "C:\out"
However, the command line (cmd) only apears quickly and closes imidiatley and nothing happens.
My files are not directly in C:\ but in "C:\Users\James\Desktop\", therefore I wrote the command as such:
for %%A in (C:\Users\James\Desktop\*.jpg) do "C:\OCR\tesseract.exe" "%%~fA" "C:\out"
...but as said before, it does not work somehow.
Also, can I change the output txt name to be the same as the input image name, like so ?
for %%A in (C:\Users\James\Desktop\*.jpg) do "C:\OCR\tesseract.exe" "%%~fA" "%%~fA"
This worked :
I got two great answers! Thanks a lot. The final thing that worked was a mix between both answers:
#Echo off
PushD C:\Program Files (x86)\Tesseract-OCR || (Echo couldn't pushd C:\OCR & Exit /B 1)
for %%A in ("C:\Users\EPFL\Google Drive\EDx PDF Maker\Cellular Mechanisms of Brain Functions\Slides\1\*.jpg") do tesseract.exe "%%~fA" "%%~dpnxA"
I don't know your program C:\OCR\tesseract.exe but I assume it needs supporting tools/files present in the C:\OCR folder, so either you have to set that folder as the current one or have it contained in your path variable.
#Echo off
PushD "C:\OCR" || (Echo couldn't pushd C:\OCR & Exit /B 1)
for %%A in ("C:\Users\James\Desktop\*.jpg") do tesseract.exe "%%~fA" "%%~dpnA.txt"
The "%%~dpnA.txt" will save the text with same drive/path/filename and extension .txt
Use a for loop to iterate over the files:
for %%A in (C:\*.jpg) do "C:\OCR\tesseract.exe" "%%~fA" "C:\out"
%%A is the filenames (one at each run of the loop),
%%~fA is the fully qualified filename (just to be sure).
Read the output of for /? to learn more about those modifiers.
Note: this is batchfile syntax. To use it directly on command line, replace every %% with a single %

How to find and select newest file in a directory and restore with SQLRestore?

I want to make a batch or cmd file to automatically select the latest file in the directory D:\Romexis_Bilder\romexis_SQL_Backup. These are ZIP SQL backup files that are generated two times daily in the format yymmddhhmm.zip, e.g Romexis_db201805271200.zip on a server running Windows 2016 Server.
The latest added file to the directory (result of FOR /F) should then be used in SQL RESTORE (backup and ftp program Windows).
The idea was to use the FOR command
My draft:
Go into the directory:
pushd "D:\Romexis_Bilder\romexis_SQL_Backup"
Find the latest file. (I don't really know how to set the parameters here.)
for /f "tokens=*" %% in ('dir /D:\Romexis_Bilder\romexis_SQL_Backup /od') do set newest=%%D:\Romexis_Bilder\romexis_SQL_Backup
The result of FOR should be used in *.zip
cd C:\Program Files (x86)\Pranas.NET\SQLBackupAndFTP\
SqlRestore D:\Romexis_Bilder\romexis_SQL_Backup\*.zip -db Romexis_db -srv .\ROMEXIS -pwd password disconnect Romexis_db
I stuck with FOR, but don't know if there would also be another possibility.
I don't know if the last command line in question is really correct. I have some doubts output this line.
But this code can be used to get the name of the newest *.zip file according to last modification date without path.
#echo off
set "BackupFolder=D:\Romexis_Bilder\romexis_SQL_Backup"
for /F "eol=| delims=" %%I in ('dir "%BackupFolder%\Romexis_db*.zip" /A-D-H /B /O-D /TW 2^>nul') do set "NewestFile=%%I" & goto DatabaseRestore
echo ERROR: Could not find any *.zip backup file in folder:
echo "%BackupFolder%"
echo/
pause
goto :EOF
:DatabaseRestore
cd /D "%ProgramFiles(x86)%\Pranas.NET\SQLBackupAndFTP"
SqlRestore.exe "%BackupFolder%\%NewestFile%" -db Romexis_db -srv .\ROMEXIS -pwd password disconnect Romexis_db
echo/
pause
FOR executes in a separate command process started with cmd.exe /C in background the command line:
dir "D:\Romexis_Bilder\romexis_SQL_Backup\*.zip" /A-D-H /B /O-D /TW 2>nul
DIR outputs to handle STDOUT of background command process
only names of non hidden files because of /A-D-H (attribute not directory and not hidden)
in bare format because of /B just the file name with file extension, but without file path
sorted reverse (newest first) by date because of /O-D
using write time (last modification time) because of /TW
in directory D:\Romexis_Bilder\romexis_SQL_Backup matching the pattern Romexis_db*.zip.
I recommend running this command line in a command prompt window to see at least once what DIR outputs.
DIR would output an error message to handle STDERR in case of no *.zip file found or the directory does not exist at all. This error message is suppressed by redirecting it to device NUL.
Read also the Microsoft article 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.
FOR captures the output written to STDOUT and processes the output line by line with ignoring empty lines which do not occur here because of DIR with option /B does not output empty lines.
FOR with option /F would ignore lines starting with a semicolon by default. For that reason end of line character is redefined with eol=| from ; to a vertical bar which file names can't contain. eol=| would not be required in this case because of file name pattern Romexis_dbYYYMMDDhhmm.zip making it unlikely that a file name starts with a semicolon.
FOR with option /F would split up the lines into substrings using space/tab as delimiter and would assign for each line only first space/tab delimited string to specified loop variable I. This line splitting behavior is disabled by specifying an empty list of delimiters with delims=. delims= would not be required in this case because of file name pattern Romexis_dbYYYMMDDhhmm.zip making it unlikely that a file name contains a space character.
The name of the file output first by DIR which is the newest ZIP file in specified directory is assigned to environment variable NewestFile. And next the FOR loop is exited with a jump to label DatabaseRestore as all other file names output by DIR are of no interest for this task.
The command lines below the FOR command line are executed only if there is no *.zip file in specified directory which report this unexpected error case.
It would be also possible to use the DIR command line below in batch file because of file name pattern Romexis_dbYYYMMDDhhmm.zip:
dir "%BackupFolder%\Romexis_db*.zip" /A-D-H /B /O-N 2^>nul
The same command line for execution from within a command prompt window:
dir "D:\Romexis_Bilder\romexis_SQL_Backup\*.zip" /A-D-H /B /O-N 2>nul
The order of the file names in output is here reverse by name which results in printing first the Romexis_db*.zip with newest date/time in file name thanks to date/time format YYYMMDDhhmm.
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.
cd /?
dir /?
echo /?
for /?
goto /?
pause /?
set /?
See also:
Where does GOTO :EOF return to?
Single line with multiple commands using Windows batch file
#Mofi
Thanks you for all your work it helped a lot!
As you advised I used each command in command prompt first to see the outputs (adapted batch %%I to cmd %I and vice versa)
I'm now able to find the newest file in D:\Romexis_Bilder\romexis_SQL_Backup the result is processed an taken as variable into the restore of the database which is done with One-Click SQL Restore https://sqlbackupandftp.com/restore
I did some modification in syntax of your commands O:D since „- „ excludes, removed attribute /TW because it was only listing backups from 2017.
#echo off
set "BackupFolder=D:\Romexis_Bilder\romexis_SQL_Backup"
for /F "eol=| delims=" %I in ('dir "%BackupFolder%\Romexis_db*.zip" /A-D-H /B /O:D 2^>nul') do set "NewestFile=%I" & goto DatabaseRestore
echo ERROR: Could not find any *.zip backup file in folder:
echo "%BackupFolder%"
echo/
pause
goto :EOF
:DatabaseRestore
cd /D "%ProgramFiles(x86)%\Pranas.NET\SQLBackupAndFTP"
SqlRestore.exe "%BackupFolder%\%NewestFile%" -db Romexis_db -srv .\ROMEXIS -pwd password
echo/
pause
Maybe the ^ in 'dir "%BackupFolder%\Romexis_db*.zip" /A-D-H /B /O:D 2^>nul' is not correct in CMD but didn‘t seem affect the result.
It was really advance! Now the GUI of One-Click SQL Restore opens with the newest *zip . The only thing that I still need to get out, is the syntax in command prompt for the restore, now i still need to click on the restore button of the GUI. Or try it over Microsoft Visual Studio SQL or command line tool.
#MOFI no modifications are made to files from 2017 or other files at all, files are not overwritten or modified later, a new file is always created by the back up program 2 times a day with the naming romexis_dbYYYMMDDhhmm.ziptwo times a day. Will try /O-N
THANKS a lot fo you input

Save output from FIND command to variable

Like the title says, I'm trying to take the output from a FIND command and save it to a variable. Specifically, I'm using:
DIR /b /s "C:\" | FIND "someexe.exe"
to locate a specific .exe file, which seems to work fine, but then I want to save the results of FIND to use later in the same script.
I've tried various different tweaks of:
for /f "usebackq" %%i in (`DIR /b /s "C:\" | FIND "someexe.exe"`) do SET foobar=%%i
but when I try to run the script the command window immediately closes (presumably due to some error, I tried putting a PAUSE command in the next line to no avail).
I assume it's some stupid minor thing that I'm doing wrong but if someone could show me what it is I'd appreciate it. Just for further reference, I don't care how many copies of "someexe.exe" exist, I just need the path for one of them.
You should be getting this error: | was unexpected at this time.. Your immediate problem is unquoted special characters like | must be escaped using ^ when they appear in a FOR /F ('command').
for /f "usebackq" %%i in (`DIR /b /s "C:\" ^| FIND "someexe.exe"`) do SET foobar=%%i
It sounds like you are running your batch file by double clicking from either your desktop or Windows Explorer. That works, but then the window immediately closes after the batch terminates. In your case it terminates before reaching PAUSE because of the syntax error.
I always run my batch files from a command window: From the Start menu you want to run cmd.exe. That will open up a command console. Then CD to the directory where your batch file resides and then run the batch file by typing its name (no extension needed). Now the window stays open after the script terminates. You can examine your variables using SET, run another script, whatever.
There is no need to use FIND in your case - DIR can find the file directly. Also, the path of your file may include spaces, in which case it will be parsed into tokens. You need to set "DELIMS=" or "TOKENS=*" so that you get the complete path.
I never understand why people use USEBACKQ when they are executing a command. I only find it useful if I am trying to use FOR /F with a file and I need to enclose the file in quotes because of spaces and/or special characters.
Also, you may run across errors due to inaccessible directories. Redirecting stderr to nul cleans up the output. Here again, the > must be escaped.
for /f "delims=" %%F in ('dir /b /s "c:\someexe.exe" 2^>nul') do set foobar=%%F

Execute shortcut links from a batch file and don't wait for application to exit

I have several applications that I tend to need open at the same time, and rather than relying solely on the Startup folder to launch them at the same time (and so I can reopen all of them if some were closed at some point throughout the day) I created a folder full of shortcuts in a similar fashion to Linux's runlevel startup links. So in the folder I have shortcut links similar to:
S00 - Outlook.lnk
S01 - Notepad++.lnk
S02 - Chrome.lnk
S03 - Skype.lnk
I created a batch file that will loop through all the links that match the naming format and launch them. The contents of that batch file currently is:
#FOR /F "usebackq delims==" %%f IN (`dir /b "S* - *.lnk"`) DO "%%f"
It will launch most of the links I try just fine, but some will launch and wait for the process to exit, thus preventing further scripts from opening. Is there any way to execute the shortcuts without waiting for processes to exit within the batch file? Or is this a lost cause and I should look for a Powershell solution instead?
Things I've tried so far:
Changing the contents to
#FOR /F "usebackq delims==" %%f IN (`dir /b "S* - *.lnk"`) DO START /B /I "%%f"
It launches the command prompt in a background process, but never actually launches the target of the link.
Changing the contents to
#FOR /F "usebackq delims==" %%f IN (`dir /b "S* - *.lnk"`) DO %comspec% /k "%%f"
It launches the first link, but waits.
Try the first way, but take the /B off of the START command. That way, the process will launch in a new window, so it shouldn't cause it to wait.
With the /B, it's going to launch the process in the same window. So if that process blocks for some reason, then you won't get control back until it finishes. For example, consider the following batch file, foo.bat (you need sleep command for this, I have cygwin so it comes with that):
echo hi
sleep 5
From a command prompt, if you type
START /B foo.bat
you'll notice that control won't come back to the command prompt until the sleep finishes. However, if we do this:
START foo.bat
then control comes back immediately (because foo.bat starts in a new window), which is what you want.
dcp's answer pointed in the right direction by trying it without the /B flag, but it wasn't the solution. Apparently START will take the first quoted string, regardless of the order of parameters passed to it, as the title of the new window rather than assuming it is the executable/command. So when the START processes launched they had the shortcut links as the title of the window, and the starting directory was the working directory of the main batch file. So I updated my file to batch file to the following and it works:
#FOR /F "usebackq delims==" %%f IN (`dir /b "S* - *.lnk"`) DO START /B /I "TITLE" "%%f"

Resources