I am using this batch to automatically restart some program, they are running very well, but sometimes the batch exit, which causes process_1 and process_2 also exit. It seems that everything is normal, but the batch itself crashes. Why ?
#echo off
cd %~dp0
set process_1=process_1.exe
set process_2=process_2.exe
set interval=10
:check_service
tasklist > task_tmp.txt
findstr %process1% task_tmp.txt> NUL
if ErrorLevel 1 (
timeout /t 1 /nobreak > NUL
goto start_1
)
findstr %process2% task_tmp.txt> NUL
if ErrorLevel 1 (
timeout /t 1 /nobreak > NUL
goto start_2
)
timeout /t %interval% /nobreak > NUL
goto check_service
:start_1
start /b "" %process_1%
echo %date% %time% %process_1% " down, up it" >> start_note.txt
goto check_service
:start_2
start /b "" %process_2%
echo %date% %time% %process_2% " down, up it" >> start_note.txt
goto check_service
You can maybe simplify like this:
#echo off
Set "MyProcess1=process_1.exe"
Set "MyProcess2=process_2.exe"
:check
%SystemRoot%\System32\tasklist.exe /NH | %SystemRoot%\System32\find.exe /i "%MyProcess1%">nul || echo starting %MyProcess1% && start "process 1" "%MyProcess1%"
%SystemRoot%\System32\tasklist.exe /NH | %SystemRoot%\System32\find.exe /i "%MyProcess2%">nul || echo starting %MyProcess2% && start "Process 2" "%MyProcess2%"
%SystemRoot%\System32\timeout.exe /t 10 /nobreak >nul
goto check
Full qualified file names are used for the commands tasklist, find and timeout to make this batch file independent on the values of the local environment variables PATH and PATHEXT and to avoid that the Windows command processor has to search for these three executables.
You can shorten your code like this:
#echo off
pushd "%~dp0"
:chkservice
tasklist | find /I "Process_1.exe" >nul 2>&1
if errorlevel 1 (
start Process_1.exe
echo %date% %time% Process_1.exe Down up, it >>startnote.txt
)
tasklist | find /I "Process_2.exe" >nul 2>&1
if errorlevel 1 (
start Process_2.exe
echo %date% %time% Process_2.exe Down up, it >>startnote.txt
)
timeout /t 10 /nobreak >nul 2>&1
goto chkservice
Related
I have to record a session with a program and want the windows task (1hour) to run a .Bat file to hit for example "F1" to stop the recording then run another .bat file to shutdown the pc.
I dont have problem with turning off pc but the one for "F1".
This is the code i thought it gonna work.
#echo off
cd "C:\Program Files\ShareX"
Start "" /b sharex.exe
timeout /T 5 /nobreak >nul
%SendKeys% "{F1}"
timeout /T 5 /nobreak >nul
taskkill /IM sharex.exe /F
Thanks
So, if I understood this question...
This will create the sendkey.vbs to you and run it in your code...
{ sorry my limited English }
#echo off & setlocal enabledelayedexpansion
set "_temp_vbs=%temp%\_temp_file_4vbs_.vbs"
>"!_temp_vbs!"^
(
echo/ Set WshShell = WScript.CreateObject^("WScript.Shell"^)
echo/ Set objShell = WScript.CreateObject^("WScript.Shell"^)
echo/ Wscript.Sleep 1500
echo/ objShell.AppActivate "sharex.exe"
echo/ Wscript.Sleep 1500
echo/ WshShell.SendKeys "({F1})"
)
cd /d "C:\Program Files\ShareX" & Start "" /b sharex.exe
timeout /t 3600 /nobreak && start "" /w "%Windir%\System32\wScript.exe" //nologo "!_temp_vbs!"
>nul 2>nul ((
tasklist | findstr /lic:"ShareX.exe"
) && (
timeout /t 5 /nobreak >nul & taskkill /f /im "ShareX.exe" & del /q /f "!_temp_vbs!"
) || (
call shotdown_pc.bat & exit /b
)) >nul 2>nul
My batch-file program always crashes at the same point. What always happens before it crashes is this:
ping -n 6 127.0.0.1 1>nul: 2>nul:
-n cant be processed syntactically at this point.
if ping -n 1 127.0.0.1|find "(0" >nul && goto Loop
And then the window closes.
Could maybe someone help me fix the problem?
This is the whole script:
#setlocal enableextensions enabledelayedexpansion
:Loop
set ipaddr=127.0.0.1
ping -n 6 %ipaddr% >nul: 2>nul:
if ping -n 1 %ipaddr%|find "(0%" >nul && goto Loop
echo Connection lost
start "" http://www.google.com
else if ping -n 1 %ipaddr%|find "(100%" >nul && goto Loop
echo Connection OK
taskkill /FI "WINDOWTITLE eq google*" goto Loop
endlocal
Here is an advanced Version with two blocks of code that are executed dependent of whether Connection is ok or lost.
#setlocal enableextensions enabledelayedexpansion
set ipaddr=127.0.0.1
:Loop
ping -n 6 %ipaddr% >nul: 2>nul:
ping -n 1 %ipaddr%|find "(0%" >nul && (
echo Connection OK
taskkill /FI "WINDOWTITLE eq google*"
) || (
echo Connection lost
tasklist /v /fi "Windowtitle eq google*" || start "" http://www.google.com
)
goto :Loop
This is the "conventional way" with %errorlevel% and if- else (same logic, the above is just a shorter way of doing it):
#setlocal enableextensions enabledelayedexpansion
set ipaddr=127.0.0.1
:Loop
ping -n 6 %ipaddr% >nul: 2>nul:
ping -n 1 %ipaddr%|find "(0%" >nul
if %errorlevel%==0 (
echo Connection OK
taskkill /FI "WINDOWTITLE eq google*"
) else (
echo Connection lost
tasklist /v /fi "Windowtitle eq google*" || start "" http://www.google.com
)
goto :Loop
I took set ipaddr... out of the Loop. No Need to do it again and again.
(just wondering, if Google would be reachable, if the Connection got lost...)
EDIT to reflect the last comment. A bit enhanced, so any action only happens, if the connection status changes. Delete the "log" function if you don't need it, or redirect them to a file, if you like.
#echo off
setlocal enabledelayedexpansion
set ipaddr=127.0.0.1
set "status=undefined"
:Loop
ping -n 2 %ipaddr% >nul: 2>nul:
ping -n 1 %ipaddr%|find "(0%" >nul && (
set oldstatus=!status!
set status=online
if !status! neq !oldstatus! (
echo %date% %time% Connection switched from !oldstatus! to !status!
taskkill /FI "WINDOWTITLE eq google*" >nul 2>&1
)
) || (
set oldstatus=!status!
set status=offline
if !status! neq !oldstatus! (
echo %date% %time% Connection switched from !oldstatus! to !status!
start "" http://www.google.com
)
)
goto :Loop
I have a batch file that moves some things around and organizes them. I want to add to the end of that batch some code to rename all the files to their same name but the date in addition to the end in only numbers. Maybe I'm bad at searching because I swear this has been covered but I just couldn't find it. So to summarize, I need help writing code that will convert every file in the folder that does not already have the date at the end, to have the date added to the end. So it needs to check whether there are 8 digits at the end and if not then add the date. I'll post my batch file just in case you need to know what I'm doing
rem #echo off
SETLOCAL enableextensions
Set dat=Date
for %%x in (*.pdf) do (
set "_pdfname=%%x"
call :doAllWork
)
goto :eof
:doAllWork
ECHO start
start %_pdfname%
TIMEOUT /T 2 /NOBREAK
start select.vbs
TIMEOUT /T 1 /NOBREAK
start copy.vbs
TIMEOUT /T 1 /NOBREAK
for /F %%g in ('
wmic OS get LocalDateTime /value^|findstr "="
') do for /F %%G in ("%%g") do set "_%%G"
echo %_LocalDateTime:~0,14%
type NUL > TextFiles\%_LocalDateTime:~0,14%.txt
start TextFiles\%_LocalDateTime:~0,14%.txt
TIMEOUT /T 2 /NOBREAK
ECHO close PDF
start close.vbs
TIMEOUT /T 2 /NOBREAK
start window.vbs
TIMEOUT /T 1 /NOBREAK
start paste.vbs
TIMEOUT /T 1 /NOBREAK
start save.vbs
TIMEOUT /T 1 /NOBREAK
start close.vbs
start enter.vbs
move /-y "%_pdfname%" "OldTimesheets\"
TIMEOUT /T 1 /NOBREAK
ECHO exit loop
if exist *.pdf (
goto :eof
) else (
goto :end
)
:end
cscript MessageBox.vbs "This will be shown in a popup."
So at the End all of the new PDFs in OldTimesheets need to be renamed but the old ones will have the date they were put in there.
Thanks ahead of time! This Community is always great!
#echo off
SETLOCAL enableDelayedExpansion
for /f "delims=" %%x in ('dir /b *.pdf') do (
call :doAllWork "%%x"
)
for /f "delims=" %%x in ('dir /b *.pdf') do (
echo %%x | findstr /r "_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\." >nul
if errorlevel 1 ren "%%x" "%%~fx_!_LocalDateTime:~0,8!%%~nx"
)
cscript MessageBox.vbs "This will be shown in a popup."
pause
exit
:doAllWork
ECHO start
start %1
TIMEOUT /T 2 /NOBREAK & start select.vbs
TIMEOUT /T 1 /NOBREAK & start copy.vbs
TIMEOUT /T 1 /NOBREAK
for /F "delims== tokens=2" %%g in ('
wmic OS get LocalDateTime /value ^| find "="
') do set _LocalDateTime=%%g
echo !_LocalDateTime:~0,14!
type NUL > TextFiles\!_LocalDateTime:~0,14!.txt
start TextFiles\!_LocalDateTime:~0,14!.txt
TIMEOUT /T 2 /NOBREAK & ECHO close PDF & start close.vbs
TIMEOUT /T 2 /NOBREAK & start window.vbs
TIMEOUT /T 1 /NOBREAK & start paste.vbs
TIMEOUT /T 1 /NOBREAK & start save.vbs
TIMEOUT /T 1 /NOBREAK & start close.vbs & start enter.vbs
move /-y "%1" "OldTimesheets\"
TIMEOUT /T 1 /NOBREAK & ECHO exit loop
exit /b
Notes:
Replaced direct enumeration of *.pdf with dir /b *.pdf to prevent possible re-processing of files after they have been renamed.
Added SETLOCAL enableDelayedExpansion to make _LocalDateTime change its value at each assignment, also ! instead of % should be used in such case
Removed SETLOCAL enableextensions as it's enabled by default
Simplified a few things to improve readability
I figured it out on my own! I added
set str=%date%
echo.%str%
set str=%str:/=%
echo.%str%
at the begging and used
ren OldTimesheets\%_pdfname% %str%%_pdfname%
right after the move line. Works like a charm! Thanks for the help anyways!
I have a little problem with the next code
#Echo off
Title STARTING
cls
echo.
echo Checking running services...
echo.
timeout /t 2 /nobreak >NUL
tasklist /fi "imagename eq cmd.exe" /v | find /I /N "DATABASESERVER" >NUL
if "%ERRORLEVEL%"=="1" (
cls
echo.
echo Database is not running, now will start!
echo.
start database.bat
echo Database is running!
echo.
timeout /t 4 /nobreak >NUL
)
tasklist /fi "imagename eq cmd.exe" /v | find /i /n "ARMASERVER" >NUL
if "%errorlevel%"=="1" (
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do (
set /A "ora=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
echo %ora%
pause
cls
echo.
echo Server is not running, now will start!
echo.
start arma.bat
title EPOCHSERVER
timeout /t 39 /nobreak >NUL
)
The problem is that "echo %ora%" it give me the result "Echo off" instead the value of time in seconds
What is the problem?
Thank you in advance!
You need to enable delayed expansion:
tasklist /fi "imagename eq cmd.exe" /v | find /i /n "ARMASERVER" >NUL
if "%errorlevel%"=="1" (
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do (
set /A "ora=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
echo percent inside ^(^)=%ora%
setlocal enabledelayedexpansion
echo exclamation=!ora!
endlocal
)
echo percent outside ^(^)=%ora%
Output:
==>D:\bat\SO\30834591.bat
percent inside ()=
exclamation=214860
percent outside ()=214860
==>
%ora% is empty at that point, which means that the command being executed is just echo, which returns the state of echo.
Are you sure that the quotation marks on the set line should be there?
Someone with better batch skills will speak up; I don't want to risk misleading you with my half-educated guesses.
In the meantime, I recommend that you play with that line directly on the commandline until you get the results you expect. Remember to de-double the % characters outside of the batch script.
I want to find a string in a file using DOS:
For example
find "string" status.txt
And when it is found, I want to run a batch file.
What is the best way to do this?
It's been awhile since I've done anything with batch files but I think that the following works:
find /c "string" file
if %errorlevel% equ 1 goto notfound
echo found
goto done
:notfound
echo notfound
goto done
:done
This is really a proof of concept; clean up as it suits your needs. The key is that find returns an errorlevel of 1 if string is not in file. We branch to notfound in this case otherwise we handle the found case.
C:\test>find /c "string" file | find ": 0" 1>nul && echo "execute command here"
#echo off
cls
MD %homedrive%\TEMPBBDVD\
CLS
TIMEOUT /T 1 >NUL
CLS
systeminfo >%homedrive%\TEMPBBDVD\info.txt
cls
timeout /t 3 >nul
cls
find "x64-based PC" %homedrive%\TEMPBBDVD\info.txt >nul
if %errorlevel% equ 1 goto 32bitsok
goto 64bitsok
cls
:commandlineerror
cls
echo error, command failed or you not are using windows OS.
pause >nul
cls
exit
:64bitsok
cls
echo done, system of 64 bits
pause >nul
cls
del /q /f %homedrive%\TEMPBBDVD\info.txt >nul
cls
timeout /t 1 >nul
cls
RD %homedrive%\TEMPBBDVD\ >nul
cls
exit
:32bitsok
cls
echo done, system of 32 bits
pause >nul
cls
del /q /f %homedrive%\TEMPBBDVD\info.txt >nul
cls
timeout /t 1 >nul
cls
RD %homedrive%\TEMPBBDVD\ >nul
cls
exit
We have two commands, first is "condition_command", second is "result_command".
If we need run "result_command" when "condition_command" is successful (errorlevel=0):
condition_command && result_command
If we need run "result_command" when "condition_command" is fail:
condition_command || result_command
Therefore for run "some_command" in case when we have "string" in the file "status.txt":
find "string" status.txt 1>nul && some_command
in case when we have not "string" in the file "status.txt":
find "string" status.txt 1>nul || some_command
As the answer is marked correct then it's a Windows Dos prompt script and this will work too:
find "string" status.txt >nul && call "my batch file.bat"
That's more straightforward:
find /c "string" file
if %errorlevel% not equ 1 goto something