I am trying to create a batch file which is doing these things :
move some folder
call another batch file
copy the result of batch file to clipboard
run the imacros (imacros will use the clipboard)
So the important thing is I have to be sure for every step that it is completed. Because every step is attached together.
My question is how can I do that ? I read something about SLEEP, PING, TIMEOUT, PAUSE etc.. But I cannot know very much prons and cons. Could someone give some tips about these commands or which should i use for safe programming ?
Not : I am working on windows xp and windows server 2008
And here is my batch code :
#echo off
set cwd=D:\workset\xx\yyy\
set wp=D:\workset\xx\yyyy\zzzzz\
:: ensure folder exist
mkdir %cwd% > nul 2>&1
mkdir %wp%\done > nul 2>&1
d:
cd %wp%
:export
::echo tidy folder %wp%
for %%i in (xx_to_yy*.zip) do (
move "%%i" "done\%%i"
)
echo call %cwd%aaa_bbb_export.bat
call %cwd%aaa_bbb_export.bat 5555
#echo off
for %%i in (xx_to_yy*.zip) do (
echo %wp%%%i | clip
move "%%i" "done\%%i"
)
#echo off
:finish
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" http://www.google.com
ping 127.1.1.1
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" imacros://run/?m=yyy.iim
Using the pause and echo command is a great way to debug a piece of scrip in batch.
Simply add:
Echo Task Complete: [Description] : Continue ?&>nul pause
At the end of every task. That way, you can check if everythings fine before giving the all clear for you batch file to continue. Later on, you'll learn to do error checking in batch files, in which case you could do something similar with an error message and include soloutions as options.
Edit:
If you wish to automate the script, so that it doesn't need user input, and instead attempts to check ikf an error occured you could either:
Check manualy, that is 1: check if folder has moved, 2: check if other batch file did what it needed (create new files etc.) 3: check if clipboard has suffiecent lines to be result of batch files (maybe clear it at the start) and lastly, check if imacros did what was needed
Check if commands were succeful. (redirec errors to a text file and then see if they were any.
Since, I don't know exactly what you are doing, I can only help you wit case 2 (though 1 would be better). You redirect the errors as so:
command [parameters] 2>>errors.log
And at the end of every section:
set /p error=<errors.log
if defined error (
Echo An Error Occured : Last Step == [Step Description]
ECHO ---------- RUN : %Date% %Time% ----------
type errors.log >> error-log.txt
del errors.log
if "%~1"=="RESTART" (
Echo Error Occured Two Times in a Row . . .
Echo Exiting in 20 seconds . . .
Exit /b 9
)
Echo Restarting procedure in 60 seconds . . .
sleep 60
Start %~f0 "RESTART"
Exit
)
The above code will check if there were any errors, add them to a log called error-log.txt. If there is an error, it will restart and if there is an error again, it will exit. There will be a small pause before either of these events, incase you want to cancel it (simply close)
Hope you found this helpful,
Mona.
First option is, after each "critical" command, check for errorlevel
copy someThing someWhere
if errorlevel 1 (
rem something goes bad
goto somewhereToHandleIt
)
Alternatively, you can add code to check that the operation was sucessful, testing everything is where it is supossed to be. But first option is usually better. Trust the system, it will do the work and report when problems found.
Related
It's hard for me to explain my problem, so let's see the code :
#echo off
cls
set errors=0
bin\behat > test.txt || set /A errors=errors+1
if %errors% EQU 0 goto ok
goto ko
:ok
echo .
echo .OK
goto end
:ko
echo .
echo .KO
:end
When I launch this batch file, I never see the OK/KO output. It looks like the batch stopped after the call to behat. But I need it to continue, in order to detect errors and manage them.
This batch works fine with other calls and I need behat being called after them. Has someone an idea to resolve this ?
Thanks
You are calling bin\behat.bat, a batch file.
When a batch file directly invokes another one, the execution flow is transfered to the called one and does not return to the caller.
To call another batch file and allow the execution to return to the caller, you will need to use the call command
....
call bin\behat > test.txt || set /A errors=errors+1
....
Me and couple of my friends are using a shared folder on Dropbox, where've uploaded our minecraft server. The point of this is that anyone can launch a server at any time, insted of one person having to run it all the time.
The only problem is, two people might launch the server at the same time, and overlapping save files might occur. To combat this, I want to write a simple batch file.
The logic is this:
IF the process "minecraft_server.1.8.1" is running, rename the the server folder to "RUNNING AS _INSERT_NAME_HERE_", ELSE rename it back to "Minecraft server"
The NAME would be read as a computer name (if that's at all possible), or from some txt file that a user would create (to write their own name)
I've never written a batch file and I don't know if this is possible, but it seems simple enough and any help would be appreciated.
Thank you in advance.
Ok so after a bit of tinkering, I wrote my first batch file. For the most part it seems to be working, however I can't seem to implement a proper loop.
#echo off
IF EXIST *_RUNNING.txt (
echo "ERROR, SERVER ALREADY RUNNING as %computername%"
pause
EXIT
) ELSE (
copy NUL %computername%_RUNNING.txt
START /WAIT minecraft_server.1.8.1.exe
tasklist /FI "IMAGENAME eq javaw.exe" 2>NUL | find /I /N "javaw.exe">NUL
:loop
IF "%ERRORLEVEL%"=="0" (
TIMEOUT /t 5
GOTO loop
) ELSE (
del %computername%_RUNNING.txt
echo "Server ended."
pause
EXIT ) )
When I start minecraft_server.1.8.1.exe it then launches javaw.exe, and that is the actual process that starts the server. After that I just check if the process is still running or not. However I can't seem to loop that particular part of the code, I keep getting synatx errors.
This is not exactly what you are looking for in the topic of the question, but if I get it right you would like to avoid that a server is started twice. So I would do the following:
Create a batch-file that:
First checks if a file named *_MinecraftServer.txt exists. If yes, it assumes that the server is already running and simply exits.
If no such file exists, it creates the file.
Then it starts the server.
Once the server exits, the file is deleted.
This would be something like this:
#echo off
REM Define a filename for the text-file informing other people that a server is running
SET FILENAME=%computername%_MinecraftServer.txt
REM Check if such a file already exists, if not refuse to start:
if exist *_MinecraftServer.txt (
REM Such a file exists, print the content of the file:
echo "ERROR, SERVER ALREADY RUNNING"
type *_MinecraftServer.txt
) else (
REM No such file is found. Create a file, then start the server process.
echo "SERVER is running on %computername%" > %FILENAME%
REM replace the notepad.exe with the name of the server.exe (and all params it requires)
REM Maybe you will also need to write the full-path to the server
notepad.exe
REM Once the server exits, remove the file
del %FILENAME%
echo "Server exited"
)
REM Require the user to hit a key before exiting the batch:
pause
This sample batch starts a notepad.exe and created a file COMPUTERNAME_MinecraftServer.txt.
You would have to replace notepad.exe with the path to the minecraft server exe.
Note that I'm not sure if this batch works if any of the directories involved contains spaces.
And of course this only works if from now on all people start the server only using the batch-file.
Also, theoretically multiple servers can be run if multiple users start the server at more or less the same time, as there is some delay until dropbox will have uploaded and distributed the created txt-file.
My question is how would I make a batch script instead of closing when the X in the top right is pressed to execute a file called exit.exe.
There are a couple points in this question that are not clear enough:
If you want that when the rigth top X is pressed on the cmd.exe window it not close, but do a different thing instead, then there is no way to achieve such thing with any existent window, that is, with the windows of all existent applications.
If you want to differentiate if the window that execute your Batch file terminated normally or terminated because the user click on the right top X, then the way to achieve that is via a previous "starter" program that execute your Batch file and expects a certain value returned from it. If the returned value is not the expected one, then it is assumed that the window was cancelled via the right top X.
starter.bat:
#echo off
echo Start yourScript.bat:
start "" /W yourScript.bat
echo Value returned from the script: %errorlevel%
if %errorlevel% neq 12345 ECHO execute exit.exe
yourScript.bat:
#echo off
echo I am the script.bat
set /P var=input value:
rem Terminate normally:
exit 12345
the [X] is "out of reach" for cmd. Only way, I can think of is: create another cmd to watch the presence of the current window:
#echo off
title WatchMe
more +7 %~f0 >t2.bat
start "watcher" t2.bat
exit /b
#echo off
:running
tasklist /v|find "WatchMe" >nul &&echo waiting || goto finished
timeout 1 >nul
goto running
:finished
echo "the process has finished
I would like to start the Apache service on my Windows 7 with the help of a batch program. That's a really simple task, all I have to do is type this:
net start Apache2.2
then press Enter; BUT I must have admin rights to do so, otherwise I get some error messages like this:
System error 5 has occurred.
Access is denied.
It's OK, but I would like to check the output of the "net start XY" command, and in case the output (or the response) contains the mentioned "Access is denied" string, then I would like to do some other things in another part of the batch program (output some custom error messages and stuff).
I tried to check the output with FIND command like this (IT DOESN'T WORK THE WAY IT SHOULD):
#echo off
set search_string=Access is denied
echo We are looking for this string: "%search_string%"
rem set errorlevel =
net start Apache2.2 | find /i "%search_string%" > nul
echo The errorlevel number is: "%ERRORLEVEL%"
if %ERRORLEVEL% EQU 0 goto gotcha
if %ERRORLEVEL% EQU 1 goto not_found
if %ERRORLEVEL% EQU 2 goto para
:gotcha
echo OK, found it
echo So maybe you don't have the rights to do so...
goto end
:not_found
echo String not found...
echo So this would mean there are no problems related to admin-rights... but YES, there are... :-S
goto end
:para
echo Something's not OK...
goto end
:end
echo -- END --
pause
Starting this batch program without admin rights, it outputs the mentioned "Access is denied", so it should jump to "gotcha" label. Unfortunately it doesn't work fine, it jumps to "not_found", which means it didn't find the given string ("Access is denied").
Maybe the problem is that
net send XY
command sends the "Access is denied" output a little bit delayed, just after checking for admin rights, and find doesn't take care about it anymore. But it's just guessing, I don't know the real explanation of the problem.
BUT the code above DOES work when I create another little batch program which just simply echoes the lines above with the "Access is denied" string. So the other little batch program, which shows that 'find' command can work the way it's written like above, looks like this:
#echo off
echo.
echo System error 5 has occurred.
echo.
echo Access is denied. blabla
echo.
I saved this file with the name "write_accessdenied_stuff.bat".
After that, I tried the code above, but instead of the "net send XY...." row I wrote this one:
write_accessdenied_stuff.bat | find /i "%search_string%" > nul
so the beginning of the code is changed like this, and IT WORKS:
#echo off
set search_string=Access is denied
echo We are looking for this string: "%search_string%"
write_accessdenied_stuff.bat | find /i "%search_string%" > nul
..........
..........
With this one, the find command sets the errorlevel to 0, which means it has found the string given, so the execution of the program jumps to "gotcha" label.
So how can I find the little bit delayed "Access is denied" output of the "net start XY" command?
Thank you very much in advance!!!
Use
net start Apache2.2 2>&1 | find /i "%search_string%" > nul
in order to tie STDERR to the standard output.
i try to make a loop in a .cmd file.
If test.txt is not exists then i will kill the cmd process.
#echo off
if not exists test.txt goto exit
But this code doesn't work and i don't know how to make a loop every 2 seconds.
Thanks for help.
The command is called exist, not exists:
if not exist test.txt goto :exit
echo file exists
:exit
About your loop:
I am not 100% sure, but I think there is no sleep or wait command in Windows. You can google for sleep to find some freeware. Another possibility is to use a ping:
ping localhost -n 3 >NUL
EDIT:
The Windows Server 2003 Resource Kit Tools contains a sleep.
See here for more information, too
If you need to wait some seconds use standard CHOICE command. This sample code check if file exist each two seconds. The loop ends if file exists:
#ECHO OFF
:CHECKANDWAITLABEL
IF EXIST myfile.txt GOTO ENDLABEL
choice /C YN /N /T 2 /D Y /M "waiting two seconds..."
GOTO CHECKANDWAITLABEL
:ENDLABEL
exit is a key word in DOS/Command Prompt - that's why goto exit
doesn't work.
Using if not exist "file name" exit dumps you out of that batch file.
That's fine if exiting the batch file is what you want.
If you want to execute some other instructions before you exit, change the label to something like :notfound then you can goto notfound
and execute some other instructions before you exit.
(this is just a clarification to one of the examples)
Using the following:
if not exist "file name" goto exit
Results in:
The system cannot find the batch label specified - exit
However using the same command without "goto" works, as follows:
if not exist "file name" exit