How to print PDF documents in batch mode? (using Windows Task Scheduler) - windows

I am trying to print in batch mode each of the PDF files contained in a Windows directory by writing a batch script which uses Adobe Acrobat Reader to filter them out, but I haven't succeeded in the <'SEVERAL-OPTIONS'> section as follows:
#echo off
SETLOCAL EnableDelayedExpansion
SET WRK_PATH="c:\a\b"
SET PDF_READER_PATH="c:\d\e"
...
cd !WRK_PATH!
for /F "tokens=*" %%a in ('dir /b/a-s *.pdf') do (
#echo File: %%~fa
**<SEVERAL-OPTIONS>**
ping localhost -4 -n 10 >nul
)
Where < SEVERAL-OPTIONS> have been:
1 - cmd /C "c:\d\e\AcroRd32.exe" /t %%~fa printerQ
2 - start "" "C:\d\e\AcroRd32.exe" /t %%~fa printerQ
3 - start /b "" "C:\d\e\AcroRd32.exe" /t "%%~fa" "printerQ"
4 - PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'C:\d\e\AcroRd32.exe'" ' /t c:\a\b\file1.pdf printerQ'
Although some of them works fine having a Windows session active, they cannot when they are scheduled as Task.

Related

Windows Batch script to read first 10 lines from a 10GB Informatica session log

the for loop in windows batch console hangs and does not work while processing huge files of 10 gb but works with smaller files less than 1 gb. Eg
FOR /F "delims=]" %%A IN (dummy.txt) DO (
...code...
)
I need a batch script that will read first 10 lines of a code from a 10 gb Informatica session log file efficiently. Is there any way to read huge files using batch programming ??
Try this:
#echo off
setlocal EnableDelayedExpansion
rem Read first 10 lines
(for /L %%i in (1,1,10) do set /P "line[%%i]=") < dummy.txt
rem Process them
for /L %%i in (1,1,10) do (
echo Line %%i- !line[%%i]!
FOR /F "delims=]" %%A IN ("!line[%%i]!") DO (
...code...
)
)
PS - I would bet this method run much faster than the PowerShell one! ;)
I suggest you use powershell for this. there are 2 basic methods:
Open powershell. Start, run(search), poweshell.exe. Then cd to the relevant directory and then run:
Get-Content dummy.txt | Select-Object -first 10
or save the above in a file with a .ps1 extenion and simply run it from there.
If you still want to use it from within a batch file, simply make some additions like below and save as a .bat or .cmd file.
powershell -command "& {Get-Content dummy.txt | Select-Object -first 10}"
If you have powershell 3 or later, you can use the new head function built-in.
from batch:
powershell -command "& {Get-Content dummy.txt -Head 10}"
Or again as pure powershell:
Get-Content dummy.txt -Head 10
To read from a huge file you can use a for /F loop and abort it using goto:
#echo off
set /A "COUNT=0, LIMIT=10"
for /F usebackq^ delims^=^ eol^= %%L in ("huge.txt") do (
set /A "COUNT+=1" & set "LINE=%%L"
setlocal EnableDelayedExpansion
rem // Do something with the current line:
echo Line !COUNT!: !LINE!
if !COUNT! geq !LIMIT! goto :QUIT
endlocal
)
:QUIT
The greatest possible length of each line is about 8190 bytes or characters. Empty lines are ignored by for /F and therefore not counted.

Batch file that deletes itself and folder that contains it

I'm trying to do the following but deleting the downloaded folder which contains the batch file fails:
NOTE: All exe's, apps, batch file etc. are contained in file.zip.
User downloads file.zip to any directory and unzips.
User runs an exe which is located in the unzipped folder.
This in turn runs two portable apps and some other things.
Once duties are performed, I remote in and run the same exe but this time I select an option that runs a batch file (located in unzipped folder) that starts a 30 second timer then is supposed to stop the apps and delete file.zip and the unzipped folder including the batch file itself.
Below is the batch file:
#echo off
mode con: cols=32 lines=7
color 4f
title
echo 30 Second Delay
echo Close window to abort
echo/
echo/
echo 0%% 100%%
SET /P var= <NUL
set count=0
:loop
PING -n 2 127.0.0.1 >NUL 2>&1
call :printline _
set /a count=count+1
if %count%==30 goto finish
goto loop
:printline
REM Print text passed to sub without a carriage return.
REM Sets line variable in case %1 intereferes with redirect
set line=%1
set /p var=%line%<NUL
exit /b
:finish
cls
color 0f
title Finished
mode con: cols=80 lines=25
echo Do NOT close this window!
echo/
echo Killing processes...
echo/
echo/
echo/
taskkill /t /f /im app1mainprocess.exe >nul
timeout /t 5 >nul
taskkill /t /f /im app2mainprocess.exe >nul
timeout /t 5 >nul
echo Do NOT close this window!
echo/
rem echo Restarting Windows Explorer...
rem timeout /t 10 >nul
rem taskkill /f /im explorer.exe >nul
rem start explorer.exe
echo Do NOT close this window!
echo/
echo Deleteing files and folders...
echo/
rem timeout /t 10 >nul
Set "Folder2Del=%~dp0"
cd ..
IF EXIST "file.zip" DEL "file.zip" /s /q >nul
rem echo %scrptDir%
echo Do NOT close this window!
echo/
echo Still working...
timeout /t 10 >nul
rd %Folder2Del% /s /q
(goto) 2>Nul & RD /S /Q "%Folder2Del%" & exit
The problem I encounter is that the folder never gets deleted. I realize my code is not correct but another reason is because one of the dll files in the unzipped folder is sometimes still in use by the dllhost.exe process.
I'm not sure if it is safe to add a line that kills the dllhost.exe process or not but my code still won't work because I have something wrong with how it deletes the batch file itself and the folder that contains it.
What lines do I need to edit and is it safe to kill dllhost.exe?
According to a link from dbenham
This does the trick:
#Echo off
Echo Ref: "http://www.dostips.com/forum/viewtopic.php?f=3&t=6491"
Set "Folder2Del=%~dp0"
cd "%~d0"
pause
(goto) 2>Nul & RD /S /Q "%Folder2Del%"
Take care the folder containing the batch is deleted
including any other files/folders without any further question!
Ok... I THINK I figured out how to do what I want by trying to delete the dll file, first, before trying to delete the entire directory. The code below looks for the problem dll and tries to delete it. If it still exists, it will try to delete the file every 30 seconds for up to 15 minutes. As soon as the dll gets deleted, the entire folder will also be deleted. If after 15 minutes the dll cannot be deleted, the remaining files in the folder will be deleted.
I still have a small issue. If I add code that kill/restarts Windows Explorer, the folder does not get deleted. Why and is there a workaround?
Below is the latest code:
#echo off
mode con: cols=32 lines=7
color 4f
title
echo 30 Second Delay
echo Close window to abort
echo/
echo/
echo 0%% 100%%
SET /P var= <NUL
set count=0
:loop
PING -n 2 127.0.0.1 >NUL 2>&1
call :printline _
set /a count=count+1
if %count%==30 goto finish
goto loop
:printline
REM Print text passed to sub without a carriage return.
REM Sets line variable in case %1 intereferes with redirect
set line=%1
set /p var=%line%<NUL
exit /b
:finish
cls
color 0f
title Uninstall
mode con: cols=80 lines=25
echo Do NOT close this window!
echo/
echo Killing processes...
tasklist /fi "imagename eq app1mainprocess.exe" |find ":" > nul
if errorlevel 1 taskkill /t /f /im "app1mainprocess.exe" > nul
tasklist /fi "imagename eq app2mainprocess.exe" |find ":" > nul
if errorlevel 1 taskkill /t /f /im "app2mainprocess.exe" > nul
timeout /t 5 >nul
rem echo Do NOT close this window!
rem echo/
rem echo Restarting Windows Explorer...
rem timeout /t 10 >nul
rem taskkill /f /im explorer.exe >nul
rem start explorer.exe
echo/
echo Deleteing file.zip if it exists...
timeout /t 5 >nul
Set "Folder2Del=%~dp0"
cd ..
IF EXIST "file.zip" DEL "file.zip" /s /q >nul
rem echo %Folder2Del%
rem Loops for 30 times in 30 second intervals (Total 15 minutes) to confirm deletion. Loop will exit after 30 loops and move on if dll cannot be deleted.
for /l %%i in (1,1,30) do (
del "%Folder2Del%name*.dll"
if not exist "%Folder2Del%name*.dll" goto Folder2Del
echo/
echo File locked! May take up to 15 minutes to delete.
echo Will stop trying 15 minutes after first attempt.
timeout /t 30 >nul
)
:Folder2Del
echo/
echo Attempting to delete the Connector folder and it's contents...
timeout /t 5 >nul
rd "%~dp0" /s /q & exit

Handle command response in windows bash

I'm writing a bash script that should restart a running process. I'm able to kill a process using the process name (pcm.exe). How ever, when i want to start the process, i want it to get the pcm.exe location from the earlier running process. This is because i don't know exactly where the program is located on different systems.
I have the following script:
wmic process where "name='pcm.exe'" get ExecutablePath /FORMAT:LIST
#taskkill /f /im pcm.exe >nul
#timeout /t 10 /nobreak >nul
#start h:/pandora/pcm.exe >nul
wmic successfully gets the PCM location:
ExecutablePath=H:\Pandora\PCM.exe
But how can i pass the response to a string and run #start (the path)?
TL;DR -
Use the set command
Details:
setlocal EnableDelayedExpansion
set "zTargetImage=notepad.exe"
set "zBinLocation=0"
for /f "skip=2 tokens=2 delims=," %%A in ('wmic process where "name='!zTargetImage!'" get ExecutablePath^,ThreadCount /format:csv 2^>^&1') do (
set "zBinLocation=%%A"
)
taskkill /f /im !zTargetImage! >nul 2>&1
timeout /t 2 /nobreak >nul
if not "!zBinLocation!"=="0" (
start "" "!zBinLocation!" >nul
)

Find out how many parent processes a batch-file is running under

I've got a batch-file that is calling itself in multiple CMD sessions, for example:
#echo off
if "%var%"=="set" goto :begin
set var=set
call cmd /c %0
:begin
echo Inside CMD session! Executed under x processes
pause
What I'm trying to accomplish is to get the number of processes a batch-file is being called from.
Normal batch file:
| Batch-file
| Batch script
Would return 1, as the batch-file is being called from the root process
Multiple process batch-file:
| Batch-file
| CMD
| Batch-file
| Batch script
Would return 2, as the batch-file is being called from another batch-file.
A possible solution would be to get the root process identifier number (PID), and then analyse the wait chain for that process, which I'm able to accomplish easily in Task Manager:
Summary:
How can I return the number of processes a batch-file is being executed under, with or without any third-party utilities?
#echo off
setlocal
if "%var%"=="3" goto :begin
set /A var+=1
cmd /C "%~F0"
goto :EOF
:begin
echo Inside CMD session!
wmic process where "name='cmd.exe'" get ExecutablePath,ParentProcessId,ProcessId > wmic.txt
for /F "skip=1 tokens=1-3" %%a in ('type wmic.txt') do (
ECHO %%a - Parent: %%b - PID: %%c
set "Parent[%%c]=%%b"
set "This=%%c"
)
set X=0
:nextParent
set /A X+=1
call set "This=%%Parent[%This%]%%"
if defined Parent[%This%] goto nextParent
echo Executed under %X% processes
Output example:
Inside CMD session!
C:\Windows\system32\cmd.exe - Parent: 3792 - PID: 4416
C:\Windows\system32\cmd.exe - Parent: 4416 - PID: 3220
C:\Windows\system32\cmd.exe - Parent: 3220 - PID: 1728
C:\Windows\system32\cmd.exe - Parent: 1728 - PID: 3560
Executed under 4 processes
I dabbled with Aacini's code to have the tree more visual
Inside CMD session
C:\WINDOWS\system32\cmd.exe - 1004:12424
C:\WINDOWS\system32\cmd.exe - 12424:12016
C:\WINDOWS\system32\cmd.exe - 12016:10592
C:\WINDOWS\system32\cmd.exe - 10592:11392
C:\WINDOWS\system32\cmd.exe - 11392:5616
Executed under 5 processes
Changed the middle part
Set "Space="
wmic process get ExecutablePath,ParentProcessId,ProcessId > wmic.txt
for /F "tokens=1-3" %%a in ('type wmic.txt') do (
if /I "%%a" equ "%ComSpec%" (
Call ECHO %%a - %%Space%%%%b:%%c
CAll Set "Space=%%Space%% "
set "Parent[%%c]=%%b"
set "This=%%c"
)
)
#echo off
setlocal
if "%var%"=="3" goto :begin
set /A var+=1
cmd /C "%~F0"
goto :EOF
:begin
echo Inside CMD session!
set /p Space=
wmic process get ExecutablePath,ParentProcessId,ProcessId > wmic.txt
for /F "tokens=1-3" %%a in ('type wmic.txt') do (
if /I "%%a" equ "%ComSpec%" (
Call ECHO %%a - %%Space%%%%b:%%c
CAll Set "Space=%%Space%% "
set "Parent[%%c]=%%b"
set "This=%%c"
)
)
set X=0
:nextParent
set /A X+=1
call set "This=%%Parent[%This%]%%"
if defined Parent[%This%] goto nextParent
echo Executed under %X% processes
pause

Windows BATCH: How to disable QuickEdit Mode for individual scripts?

QuickEdit mode can be useful if you wish to quickly highlight and copy text directly from the command prompt instead of redirecting output to a file. However, it has its drawbacks. If you have a batch script running, selecting text in the console will pause the script execution until the text is deselected. This can be a problem if the script is expected to continue without pause.
How can one disable QuickEdit mode for certain BATCH scripts?
A way that will affect the current command prompt session.
Here's quickEdit.bat . It is a self-compiled .net script so it requires .net installed (not installed by default on Winsows XP/2003).
Usage:
Enable:
quickEdit 1
Disable:
quickEdit 2
Get State:
quickEdit 3
Already answered here, update "QuickMode" setting in Windows Registry:
reg add HKCU\Console /v QuickEdit /t REG_DWORD /d 0 /f
However it will not affect currently opened window. But you can reopen a window:
:: Get QuickEdit Mode setting from Windows Registry
FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKCU\Console" /v QuickEdit`) DO (
set quickEditSetting=%%A %%B
)
if %quickEditSetting%==0x1 (
:: Disable QuickEdit Mode
reg add HKCU\Console /v QuickEdit /t REG_DWORD /d 0 /f
:: Open script in a new Command Prompt window
start "" "%~dpnx0" %* && exit
)
... script logic here ...
exit
Additional info about HKEY_CURRENT_USER\Console Registry configuration - https://renenyffenegger.ch/notes/Windows/registry/tree/HKEY_CURRENT_USER/console/index
Unfortunately, there is no way to edit the QuickEdit setting of the current CMD Console instance from command line. We can, however, temporarily disable the global QuickEdit setting and start a new console instance. There are a couple ways to do this, each with its own perks (pros) and drawbacks (cons). Both of the following solutions require the ability to modify the registry.
REGEDIT
PRO: Compatible with any common Windows system
CON: Requires the creation of temporary REG files
Code (goes at the beginning of your script):
if exist "%TEMP%\consoleSettingsBackup.reg" regedit /S "%TEMP%\consoleSettingsBackup.reg"&DEL /F /Q "%TEMP%\consoleSettingsBackup.reg"&goto :mainstart
regedit /S /e "%TEMP%\consoleSettingsBackup.reg" "HKEY_CURRENT_USER\Console"
echo REGEDIT4>"%TEMP%\disablequickedit.reg"
echo [HKEY_CURRENT_USER\Console]>>"%TEMP%\disablequickedit.reg"
(echo "QuickEdit"=dword:00000000)>>"%TEMP%\disablequickedit.reg"
regedit /S "%TEMP%\disablequickedit.reg"
DEL /F /Q "%TEMP%\disablequickedit.reg"
start "" "cmd" /c "%~dpnx0"&exit
:mainstart
REG
PRO: Does not require creation of temp files
CON: Not available on Windows 2000 and earlier without Resource Kit
CON: Different versions have different syntax (accounted for in code below)
Code (goes at the beginning of your script):
set reg50=::&set reg51=::&(reg /?>nul 2>&1 && set reg51=)
if %errorlevel%==5005 set reg50=
set qkey=HKEY_CURRENT_USER\Console&set qprop=QuickEdit
%reg51%if defined qedit_val (echo y|reg add "%qkey%" /v "%qprop%" /t REG_DWORD /d %qedit_val%&goto :mainstart)
%reg50%if defined qedit_val (reg update "%qkey%\%qprop%"=%qedit_val%&goto :mainstart)
%reg51%for /f "tokens=3*" %%i in ('reg query "%qkey%" /v "%qprop%" ^| FINDSTR /I "%qprop%"') DO set qedit_val=%%i
%reg50%for /f "tokens=3*" %%i in ('reg query "%qkey%\%qprop%"') DO set qedit_val=%%i
if "%qedit_val%"=="0" goto :mainstart
if "%qedit_val%"=="0x0" goto :mainstart
%reg51%echo y|reg add "%qkey%" /v "%qprop%" /t REG_DWORD /d 0
%reg50%if "%qedit_val%"=="" reg add "%qkey%\%qprop%"=0 REG_DWORD
%reg50%if "%qedit_val%"=="1" reg update "%qkey%\%qprop%"=0
start "" "cmd" /c set qedit_val=%qedit_val% ^& call "%~dpnx0"&exit
:mainstart
If you have another solution, feel free to post.
Slight update for option 1 that worked for me, that doesn't run it twice, on Win10, thanks.
if exist "c:\temp\consoleSettingsBackup.reg" regedit /S "c:\temp\consoleSettingsBackup.reg" & DEL /F /Q "c:\temp\consoleSettingsBackup.reg" & goto START
regedit /S /e "c:\temp\consoleSettingsBackup.reg" "HKEY_CURRENT_USER\Console"
reg add "HKCU\Console" /v QuickEdit /t REG_DWORD /d 0 /f
start "" "cmd" /c ""%~dpnx0" & exit"
exit
: START
rem your commands\scripts here
exit
quickedit.bat
::: TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAAClmdnY4fi3i+H4t4vh+LeL4fi2i+T4t4si9+qL4vi3i7Xbh4vg+LeLUmljaOH4t4sAAAAAAAAAAAAAAAAAAAAAUEUAAEwBAQBvnfBjAAAAAAAAAADgAA8BCwEGAAACAAAAAAAAAAAAABgQAAAAEAAAACAAAAAAQAAAEAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAIAAAAAIAAAAAAAADAAAAAAAQAAAQAAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAABUEQAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAudGV4dAAAAPQBAAAAEAAAAAIAAAACAAAAAAAAAAAAAAAAAAAgAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmEQAAshEAAMQRAADWEQAAlBEAAAAAAABVi+yD7AxTVos1DBBAAGr2/9aL2IXbD4T6AAAAg/v/D4TxAAAAjUX4UFP/FQgQQACFwA+E3gAAAP8VBBBAAIXAdH+KCITJdHmA+SJ1FUCKCITJdG1AgPkidGGKCITJdfTrWYD5IHRUgPkJdE9AigiEyXXv60aA+TB0doD5T3QFgPlvdRqKUAGA+kZ0BYD6ZnUNilACgPpGdFeA+mZ0UoD5MXRWgPlPdAWA+W91DYpIAYD5TnREgPludD9AigiEyXW0i134g2X0AMHrBoPjAWoAisMEMIhF/41F9FCNRf9qAVBq9f/WUP8VABBAAIvD60iLRfgkvwyA6wWLRfgMwDlF+HQPUFP/FRAQQAD32BvAQOsmM8DrIoNl9ACNRfRqAFCNRf9qAVBq9cZF/y//1lD/FQAQQACDyP9eW8nDfBEAAAAAAAAAAAAA5hEAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKYRAACyEQAAxBEAANYRAACUEQAAAAAAAP0CU2V0Q29uc29sZU1vZGUAAKQDV3JpdGVGaWxlABABR2V0Q29tbWFuZExpbmVBADMBR2V0Q29uc29sZU1vZGUAALkBR2V0U3RkSGFuZGxlAABLRVJORUwzMi5kbGwAAAAAAAAAAAAAAAAAAA==
#setlocal disabledelayedexpansion enableextensions
#echo off
if not exist quickedit.exe (
>quickedit.b64 (
for /f "delims=: tokens=1" %%# in ('findstr "^:::" "%~f0"') do echo %%#
)
certutil -f -decode quickedit.b64 quickedit.exe >nul
del /f /q quickedit.b64
)
quickedit.exe %*
on: quickedit 1
off: quickedit 0

Resources