Msgbox to prompt user if job (printing) is skip in batch - batch-file

As suggested in my previous question, 1 question per thread. So Im here to open another question. Basically I want to prompt user that printing will be skip today because nothing to print, then the user will press OK, then code will continue to shutdown the computer. I want to do this to alert user that today's printing job have been run.
So I try some code like below, it seems working but i dont know how to implement in my main code.
#echo off
Call :Msgbox
if "%errorlevel%"=="1" GOTO SHUTDOWN
exit /b
:Msgbox
echo wscript.quit MsgBox ("Printing skipped.. Press ok to shutdow the computer", 48, "Shutdown Computer") >"%temp%\input.vbs"
wscript //nologo "%temp%\input.vbs"
exit /b
:SHUTDOWN
echo "%SystemRoot%\System32\shutdown.exe -s -t 60"
PAUSE
This is part of my main code where i want to place above code.
https://stackoverflow.com/a/57609600/6409413
IF pdf file size greater than 9000byte > Print PDF for today > Then go to Shutdown
IF pdf file size less than 9000byte > Promp user using msgbox > user press OK > Skip Print PDF for today > Then go to Shutdown
Rem ------------------------------------------------------------------------
Rem 4. Printing files with sizes over 9000 bytes
Set "_Exe1=%ProgramFiles(x86)%\Foxit Software\Foxit Reader\Foxit Reader.exe"
For %%A In ("%_Dir1%\c\%_FullDateString%.pdf")Do If %%~zA GTR 9000 (
Echo Printing %%A&Echo=&"%_Exe1%" /t "%_Dir1%\c\%_FullDateString%.pdf")
UPDATE:
Sort of working for now using code below. Any others way to achieve this?
Rem ------------------------------------------------------------------------
Rem 4. Printing files with sizes over 9000 bytes
Set "_Exe1=%ProgramFiles(x86)%\Foxit Software\Foxit Reader\Foxit Reader.exe"
setlocal EnableDelayedExpansion
For %%A In ("%_Dir1%\c\%_FullDateString%.pdf")Do ( set size=%%~zA
if !size! GTR 9000 (
goto PRINT
) else if !size! LSS 9000 (
goto NOPRINT
:NOPRINT
msg * /time:0 /w Printing skipped.. Press "OK" to shutdown the computer"
goto SHUTDOWN
)
)
:PRINT
Echo "Printing %%A&Echo=&"%_Exe1%" /t "%_Dir1%\c\%_FullDateString%.pdf")"
Rem ------------------------------------------------------------------------
Rem 5. Shutting down computer
:SHUTDOWN
echo "%SystemRoot%\System32\shutdown.exe -s -t 60"
PAUSE

I really think that you're overcomplicating this unnecessarily. You're already using the shutdown command, which can pop up a dialog box to the end user.
Rem ------------------------------------------------------------------------
Rem 4. Printing files with sizes over 9000 bytes
Set "_Exe1=%ProgramFiles(x86)%\Foxit Software\Foxit Reader\Foxit Reader.exe"
Set "_Msg=skipped"
For %%A In ("%_Dir1%\c\%_FullDateString%.pdf")Do If %%~zA GTR 9000 (
Set "_Msg=finished"&Echo Printing %%A&Echo=
"%_Exe1%" /t "%_Dir1%\c\%_FullDateString%.pdf")
Rem ------------------------------------------------------------------------
Rem 5. Shutting down computer
ShutDown /S /T 60 /C "Printing %_Msg%, shutting down your computer." /D P:0:0
Note: This section is a direct replacement for the previous code I provided, it is not based upon whatever you've posted above, (which is littered with issues).

Related

How do I remove the last line on the CMD Window when running a batch file?

So I was making a batch file that allows to make other people think you can hack, and in one part it says in the CMD window
Starting hack in 10...
Starting hack in 9...
etc.
What I want to do is to instead of appearing on different lines I want the lines to change by deleting the last line that's showing on the CMD window. here's how the code for that part of the program looks like right now
echo Starting hack in 10...
timeout /t 1
echo Starting hack in 9...
timeout /t 1
echo Starting hack in 8...
timeout /t 1
echo Starting hack in 7...
timeout /t 1
echo Starting hack in 6...
timeout /t 1
echo Starting hack in 5...
timeout /t 1
echo Starting hack in 4...
timeout /t 1
echo Starting hack in 3...
timeout /t 1
echo Starting hack in 2...
timeout /t 1
echo Starting hack in 1...
timeout /t 1
tree
echo Hacking completed!
pause
I was also searching for a way to do it on stack overflow but I didn't find anything helpful so I created this account JUST TO MAKE THIS QUESTION. Please I need answers.
Edit: This question was answered, here's the link to the program with the problem fixed (if it says that it contains a virus, don't worry it's just a false positive (It's an exe file because I converted the file with BAT2EXE)): https://drive.google.com/file/d/1tg73Aa-Yi3So6OJYvYUPDdL0eAaqG9PL/view?usp=sharing
To overwrite the last line, all you have to do is a carriage return instead of a linefeed (carriage return plus line feed).
I'm using a subroutine here, params are a message string (quoted because of spaces) and a number (counter).
#echo off
setlocal EnableDelayedExpansion
REM create a CariageReturn:
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
echo Welcome to %~n0
echo/
call :spinner "Starting in" 10
echo It has now started.
echo insert payload here
goto :eof
:spinner
set counter=%2
:spinnerloop
<nul set /p ".=%~1 %counter% !CR!"
set /a counter-=1
timeout 1 >nul
if %counter% geq 0 goto :spinnerloop
Make sure, the first echo after the call is long enough to overwrite the complete message plus counter (add enough spaces if necessary) or echo a new line (echo/) if you want to keep the last message on screen.
Use Cls
echo Starting hack in 10...
timeout /t 1
Cls

How to play sound if phone connects to network?

I try to write a little batch script. It should play a sound if my phone joins my network.
#echo off
:A
ping -n 1 xxx.xxx.xxx.xx | findstr TTL && start airsiren.wav
goto A
The problem is now that if the phone is detected, it repeatedly starts the sound. But it's supposed to just play once.
Does anyone know a simple fix? Maybe with an IF condition?
I haven't been doing much with batch, but I think I got some basic knowledge.
I suggest following code:
#echo off
set "LastExitCode=1"
:Loop
%SystemRoot%\System32\ping.exe -n 1 xxx.xxx.xxx.xx | %SystemRoot%\System32\find.exe /C "TTL" >nul
if not %ErrorLevel% == %LastExitCode% set "LastExitCode=%ErrorLevel%" & if %ErrorLevel% == 0 start "Play sound" airsiren.wav
%SystemRoot%\System32\timeout.exe /T 5 /NOBREAK
if not errorlevel 1 goto Loop
PING outputs a line with TTL if there is a response on echo request and exits usually with value 0 on receiving a response and with 1 on getting no response. But PING does not always exit with 0 on a positive response which is the reason for using FIND.
FIND processes the output of PING and searches for lines containing the string TTL. FIND exits with value 0 on finding at least one line with TTL and otherwise with 1 for indicating no line found containing the search string. The output of FIND to handle STDOUT is of no interest and therefore reduced to a minimum by using option /C and redirected to device NUL.
Now the exit code of FIND is compared with an environment variable which holds last exit value of FIND initialized with value 1.
On current exit code being equal last exit code, there is no change in availability of the pinged device on network and therefore nothing to do.
Otherwise on a difference the current exit code is assigned to the environment variable for next loop run and current exit code is compared with value 0. If this second condition is true the pinged device sent the first time a positive response on echo request by PING. In this case the sound is played.
There is nothing else done on pinged device not available anymore on network, i.e. the exit code changes from 0 to 1.
Then a delay of 5 seconds is started using TIMEOUT with giving the user to break it with Ctrl+C. This reduces the processor core usage giving Windows the possibility to use the processor core for other processes and also reduces network usage when the pinged device is available at the moment on network. And of course the pinged device does not need anymore to permanently response on echo requests.
A jump to label Loop is done if TIMEOUT exited normally without a user break. Otherwise on user pressing Ctrl+C the batch file processing also ends.
TIMEOUT with parameter /NOBREAK requires Windows 7 or a later Windows version.
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.
echo /?
find /?
goto /?
if /?
ping /?
set /?
start /?
timeout /?
See also single line with multiple commands using Windows batch file for an explanation of operator & and meaning of if not errorlevel 1.
This can be fixed very easily using %errorlevel% and an IF statement.
Original script by Jelle Geerts.
#ECHO OFF
:Search
ping -n 1 "xxx.xxx.xxx.xx" | findstr /r /c:"[0-9] *ms"
if %errorlevel% == 0 (
echo Device was found!
start airsiren.wav
pause.
) else (
goto Search
)
My solution:
#echo off &:: modem_tester_xp+.bat
REM original https://www.elektroda.pl/rtvforum/topic2917839.html
setlocal EnableDelayedExpansion
rem set connection name (for newer than Win XP) from Network Connections (preferred name doesn't have space)
set _connection_name=internet
rem make file which close this script
echo #echo.^>"%~dpn0.exit"^&#del /q "%%~f0">"%~dp0close_%~nx0"
for /f "tokens=2-4 delims==." %%a in ('wmic os get Version /value ^|find "="') do if "%%~c" neq "" set "_system_version=%%~a.%%~b"
set "_con_ip="
set "_my_ip.last="
:start
::-n (seconds+1)
ping 127.0.0.1 >nul -n 3
set "_my_ip="
if not defined _con_ip call :get_con_ip "%_connection_name%"
if defined _con_ip for /f "tokens=3-5 delims= " %%p in ('route print ^|find " 0.0.0.0 "') do if "%%~r" neq "" if /i "%%~p"=="%_con_ip%" ( set "_my_ip=%%~p" ) else if /i "%%~q"=="%_con_ip%" set "_my_ip=%%~q"
rem if connection lost clean variable _my_ip.last
if not defined _my_ip (
set "_con_ip="
set "_my_ip.last="
) else if /i "%_my_ip%" neq "%_my_ip.last%" (
rem remember last connection addres
set "_my_ip.last=%_my_ip%"
call :2run
)
if not exist "%~dpn0.exit" goto start
del /q "%~dpn0.exit"
endlocal
goto :eof
:get_con_ip &::ConnectionName:return variable _con_ip
if "%_system_version%"=="5.1" (
rem XP find modem address
for /f "tokens=2 delims== " %%a in ('netsh diag show gateway WAN* ^|find "." ^|find "="') do if "!_con_ip!"=="" set "_con_ip=%%~a"
) else (
rem if newer works like win7, if not: if "%_system_version%"=="6.1" (rem Windows 7
if "%~1" neq "" for /f "tokens=1,4* delims= " %%n in ('netsh interface ipv4 show interfaces ^|find /i "%~1"') do if "!_con_ip!"=="" if /i "%%~p"=="%~1" for /f "tokens=1* delims=:" %%i in ('netsh interface ipv4 show addresses %%~n ^|find "." ^|find /i "ip"') do if "!_con_ip!"=="" set "_con_ip=%%~j"
if "!_con_ip!" neq "" set "_con_ip=!_con_ip: =!"
)
goto :eof
:2run
rem run external
rem start "modem started" /min /b cmd /c "echo %date% %time% '%_my_ip%'&pause"
start airsiren.wav
There are two problems with your code
Your code will unconditionally goes to the beginning even after the phone is connected, so it repeats playing the sound. You could use ... && (start airsiren.wav & goto :EOF) to terminate the batch file or use another label other than :EOF to do something else. But this doesn't give you the option to keep monitoring the phone for disconnection and re-connection.
You have to check the setting of the default media player (Typically Windows Media Player) and make sure that it is not set to continuously loop or repeat the media. Also it is overkill and somewhat inconvenient to launch a full fledged media player just for playing back a short notification sound, and usually you have to close the media player afterwards.
So this is the code I propose which solves the above mentioned obstacles by providing the option to continuously monitor the phone's connection status and also provide a more programmatic way to play the notification sound in a self contained player by using a hybrid BAT/JSCript solution.
#if (#Code)==(#BatchScript) /* Hybrid BAT/JScript line */
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set #PlaySound=start "" /b cscript //nologo //e:JScript "%~f0"
set "SoundFile.Connect=%SystemRoot%\media\ringout.wav"
set "SoundFile.Disconnect=?"
set "GenFail.Localized.Text=General failure"
:: set to 0 to disable continuous connection monitoring
set "ContinuousMonitoring=1"
set "PhoneIP=xxx.xxx.xxx.xxx"
set "Timeout=3000"
setlocal EnableDelayedExpansion
set "CheckGeneralFailure=1"
echo [%TIME%] Waiting for connection...
:WaitForConnection
ping -n 1 %PhoneIP% -w %Timeout% | findstr "TTL" >nul && (
echo [!TIME!] Phone Connected.
!#PlaySound! "!SoundFile.Connect!"
if %ContinuousMonitoring% NEQ 0 goto :MonitorConnection
goto :EOF
) || (
if !CheckGeneralFailure! NEQ 0 (
ping -n 1 %PhoneIP% -w 100 | findstr /i /c:"%GenFail.Localized.Text%" >nul && (
ping -n 1 -w %Timeout% 127.255.255.255 >nul
(call,) %= Set errorlevel to 0 =%
) || set "CheckGeneralFailure=0"
)
goto :WaitForConnection
)
:MonitorConnection
ping -n 1 %PhoneIP% | findstr "TTL" >nul && (
ping -n 1 -w %Timeout% 127.255.255.255 >nul
goto :MonitorConnection
) || (
echo [!TIME!] Phone Disconnected.
echo [!TIME!] Waiting for connection...
set "CheckGeneralFailure=1"
REM Play another sound for disconnect?
goto :WaitForConnection
)
goto :EOF
/*** End of batch code ***/
#end
/*** JScript Sound Player ***/
var wmpps = {
Undefined : 0,
Stopped : 1,
Paused : 2,
Playing : 3,
ScanForward : 4,
ScanReverse : 5,
Buffering : 6,
Waiting : 7,
MediaEnded : 8,
Transitioning : 9,
Ready : 10,
Reconnecting : 11,
Last : 12
};
var SoundFile;
if (WScript.Arguments.length) SoundFile = WScript.Arguments(0);
var WaitCount = 0;
var objPlayer = new ActiveXObject("WMPlayer.OCX.7");
with(objPlayer) {
URL = SoundFile;
settings.volume = 100;
settings.setMode("loop", false);
controls.play();
while(playState == wmpps.Transitioning) {
WaitCount+=1;
if (WaitCount > 200) break;
WScript.Sleep(10);
}
if (playState == wmpps.Playing) {
while(playState != wmpps.Stopped) WScript.Sleep(1000);
}
close();
}

Batch script that monitors for file changes

I need to create a batch script that continually monitors a specific file for changes, in this case, LogTest.txt.
When the file is updated it will trigger a VBScript message box, which displays the last line from within LogTest.txt. The idea is that this will continue monitoring after the message box is cleared.
I have tried using the forfiles option, but this really only lets me deal with the date and not the time. I know that PowerShell and other options are available, but for reasons that are just too long to explain I am limited to being only able to use a batch and VBScript.
Batch File:
#echo off
:RENEW
forfiles /m LogTest.txt /d 0
if %errorlevel% == 0 (
echo The file was modified today
forfiles /M LogTest.txt /C "cmd /c echo #file #fdate #ftime"
cscript MessageBox.vbs "Error found."
REM do whatever else you need to do
) else (
echo The file has not been modified today
dir /T:W LogTest.txt
REM do whatever else you need to do
)
goto :RENEW
MessageBox.vbs:
Set objArgs = WScript.Arguments
messageText = objArgs(0)
MsgBox "This is an error", vbOkCancel + vbExclamation, "Error Found"
There is an archive attribute on every file. Windows sets this attribute on every write access to the file.
You can set it with the attrib command and check it for example with:
#echo off
:loop
timeout -t 1 >nul
for %%i in (LogTest.txt) do echo %%~ai|find "a">nul || goto :loop
echo file was changed
rem do workload
attrib -a LogTest.txt
goto :loop
timeout /t 1 >nul: small wait interval to reduce CPU-Load (never build a loop without some idle time)
for %%i in (logTest.txt) do... process the file
echo %%~ai print the attributes (see for /? for details)
|find "a" >nul try to find the "a"rchive-attribute in the output of the previous echo and redirect any output to nirvana (we don't need it, just the errorlevel)
|| goto :loop works as "if previous command (find) failed, then start again at the label :loop"
If find was successful (there is the archive attribute), then the next lines will be processed (echo file was changed...)
attrib -a LogTest.txt unsets the archive attribute of the file.

Second instance of batch loop does not run

I am trying to create a DOS batch script on my Windows 7 machine. I want to execute file 123456.bat, which contains the following command and parameters:
call **startSelenium.bat** 55 someSuiteName suite-someSuite.html development 1 1 10 10
That script calls into the startSelenium.bat script below:
Setlocal EnableDelayedExpansion
SET TimeStamp=
FOR /f "tokens=1-4 delims=/ " %%i in ("%date%") do set datestr=%%l%%j%%k
FOR /f "tokens=1-4 delims=.: " %%i in ("%time%") do set timestr=%%i%%j%%k%%l
SET TimeStamp=%datestr%%timestr%
set a=2
set b=0
set /a c=%a%+%b%
FOR /l %%t IN (1, 1, %c%) do (
call :SEARCHPORT %%t
echo %startPort%
Start java -jar C:\Selenium\2\selenium-server-standalone-2.47.1.jar -port %startPort% -singleWindow -userExtensions C:\selenium\2\user-extensions.js -firefoxProfileTemplate "c:\selenium\2\ffprofiles\2rc" -htmlSuite "*chrome" "https://www.google.com" "Z:\selenium\2\environment\%4\suites\%3" "u:\results\%4\result-%1-%computername%-1234-%TimeStamp%.htm"
timeout /t 10
)
GOTO :EOF
:SEARCHPORT
netstat -o -n -a | find "LISTENING" | find ":%startPort% " > NUL
if "%ERRORLEVEL%" equ "0" (
set /a startPort +=1
GOTO :SEARCHPORT
) ELSE (
set freePort=%startPort%
echo %startPort%
GOTO :EOF
When I run the script, the first instance of the java applications runs with a free Windows port that the SEARCHPORT subroutine found; however, the second instance pops up and quits immediately. I suspect the code is using the same variable from the first time it went through the FOR loop instead of getting a new unused port number.
What am I doing wrong? I copied various parts of this code from other sources. I am obviously a nube, so plain English would be helpful. :)
You have got an delayed expansion issue.
You already enabled delayed expansion, but you don't use it. You have to replace %startPort% with !startPort! inside your for /l loop.

Batch to pattern matching in a loop

I am trying to loop through a file which contains few names and search the same with two patterns in another file and echo some statements.
Like I have two files :
1.Installers.txt
2.Progress.txt
Installers.txt
abc.jar
def.jar
tef.jar
....
....
Progress.txt
abc.jar deployment started
abc.jar deployed successfully
def.jar deployment started
So my requirement is to read the Installers.txt file one line at a time and search for the 2 patterns "abc.jar deployment started" and "abc.jar deployed successfully" and report successful or else if both patterns are yet to be found to show as still in progress.
I have tried writing below but its failing at many things while doing pattern and the logic also does not look good. can someone help here.
for /F "usebackq delims=" %%a in ("Installer.txt") do (
set /A i+=1
call echo installing %%i%% : %%a
:NOTVALID
findstr /I "%%k\ in\ progress" %1%\progress.txt
If errorlevel 1 (
echo "installation still in progress.."
PING 127.0.0.1 -n 1 >NUL 2>&1 || PING ::1 -n 1 >NUL 2>&1
goto NOTVALID
) else (
set /A i+=1
echo "installation completed.."
call set array[%%i%%]=%%a
call set n=%%i%%
)
Try the below code which suite your requirement :
cls
#echo off
for /f %%g in (Installers.txt) do type Progress.txt|findstr "%%g" || echo %%g is Yet to start , still in progress
Above code will read a single line from installer and then search for that string in file Progress.txt and then print the output if it is found or not.

Resources