Undo changes on batch file termination - windows

Is there anyway I can undo all the changes done by a batch file if it is terminated by a user? For example, if I am appending a text file and adding text, renaming files, deleting files by running a batch file... If a user terminates the batch file, is there a way to undo all changes done before it gets terminated by a user? OR anyway that I can not let the user terminate a batch file while its running?
Thanks

You can avoid that the normal user cancel a Batch file with Ctrl-C this way:
#echo off
setlocal
if "%~1" equ "NonCancelable" goto NonCancelable
echo Original!
start "" /B "%~F0" NonCancelable
echo Terminating original...
exit
:NonCancelable
echo I am non cancelable!
echo/
set "var="
set /P "var=Try to cancel me! (enter Exit to end): "
if /I "%var%" neq "exit" goto :NonCancelable
echo Terminating non cancelable...
Of course, the user can click on the window red cross to close the window...

Substantially depends on how sophisticated your users are and to which facilities they have access.
You could for instance create an invisible batch which the user-batch executes. Many examples on SO of how to do this.
Or perhaps you could create new files within the batch, then replace the existing files with the new ones (or even create a replacement directory with a completely new fileset) as the very last operation within your batch.

Related

is it possible to open a new cmd window with a batch file and use the new window as i live log?

I have created a batch file to help me write a script for an application I have on my phone that will automate touch tasks. The script I am creating will require 240x9 lines of the scripting language to complete the tasks I am wanting to complete, is there a way to open a new cmd line and output text to the new window?
So for instance right now I have each option in the batch file to write the screen touch coordinates required by the scripting language to execute my tasks out to a text file like this.
#ECHO :start>speedsearch.txt
Is it possible to pass these to a new window just to use it as a live log so if I loose my place I can refer to the log window to remind myself where I am in the creation of my script?
i do know that in a regular cmd window if i were to use.
TYPE C:\speedSearch.txt
it will print what is in the text file, so is there anyway to pass the command from my batch script to.
TYPE C:\speedSearch.txt
everytime i choose an option to add a line to the script in the file?
i already have the new window opening by using this at the beginning of my script.
start "LOGGING WINDOW" C:\WINDOWS\SYSTEM32\CMD.EXE
I just need a little help with how i pass commands to the new window, without disrupting my current session in the batch script.
This problem is about synchronization. There are several ways to start two or more execution threads in Batch files and exist several standard ways to solve the usual synchro problems. The difference in this case is that the second thread is started via a start command, so there is no way to redirect its standard input. The only way to accurately detect the end of the file in the second thread is inserting a particular line that indicate that point; in the code below, ":EOF" string is used for this purpose.
#echo off
setlocal EnableDelayedExpansion
if "%~1" neq "" goto %1
echo :start> speedsearch.txt
rem Run View Log code simultaneously with Main code
start "View Log" "%~NX0" ViewLog
:Main
set "line="
set /P "line=Enter next line: "
if not defined line goto endMain
echo %line%>> speedsearch.txt
goto Main
:endMain
rem Send the "end of file" mark
echo :EOF>> speedsearch.txt
echo File complete
goto :EOF
:ViewLog
set i=0
call :Update < speedsearch.txt
goto :EOF
:Update
set "line="
set /P "line="
if "!line!" equ ":EOF" goto :EOF
if defined line (
set /A i+=1
echo !i!- !line!
)
goto :Update

How to get an exclusive lock on a file using batch file?

I have a project I need to monitor a batch file which constantly runs to see if its still working. I have a remote machine which needs to monitor this batch file running on another server.
What i need to do is have the batch file create and exclusively lock a text file (can be empty, can be full it does not matter). This is so I can poll it from my remote machine (using an exe created by c#) to see if there is exclusive lock on the file - if so, then do nothing. If can get a lock, then raise alarm (as the batch has failed).
Understand this is probably not the best approach, but unfortunately its what I have to go with. So, is there a way to exclusively lock a file (automatically) using a batch file?
I was skeptical about this initially, but it turns out it can be done by using file redirection. Consider this example:
#echo off
if '%1' == '-lock' (
shift
goto :main
)
call %0 -lock > lockfile.txt
goto :eof
:main
echo %DATE% %TIME% - start
TREE C:\
echo %DATE% %TIME% - finish
goto :eof
Whilst the above batch is running, it is not possible to delete lockfile.txt.
Essentially, the batch checks for a '-lock' parameter. If it's not present, it re-executes itself with the -lock parameter and re-directs it's own output to lockfile.txt
It's also possible to create locks for 'critical' sections within a batch e.g.
#echo off
echo %DATE% %TIME% - started
(
echo Starting TREE
tree c:\
echo TREE finished
) > lock2.lock
echo %DATE% %TIME% - finished
Sources:
How do you have shared log files under Windows?
http://www.dostips.com/forum/viewtopic.php?p=12454
Here is a plain vanilla batch file to lock a particular file temporarily. Edit the txt path accordingly.
#ECHO OFF
powershell.exe -command "$lock=[System.IO.File]::Open('C:\test.txt','Open','ReadWrite','None');Write-Host -NoNewLine 'Press any key to release the file...';$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')"
It unlocks when you press the any key.

how to send each iteration of a loop in a batch script to a new cmd window and continue with loop

Disclaimer: I'm an engineer not a programmer, so while I do have technical knowledge, please bear with me if I am using the wrong terminology or asking the wrong questions.
I am trying to write a windows batch script that will allow me to submit multiple finite element simulations as a batch with all of the same settings. I currently have a script that works after a fashion, but it is not as efficient as I would like. My current script steps through the directories and runs the simulation in the command window before moving on to the next directory and repeating the loop. This script can be seen below:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
title BEST FRM Runs batch submission
echo This script will step through the run# directories and run the blast.k file in each run# folder. The .cmd file needs to be placed in the "FRMRuns" directory. You may need to change the reference to the LSDYNA solver if the version has changed.
SET /P ANSWER=Do you want to continue (y/n)?
if /i {%ANSWER%}=={y} (goto :yes)
if /i {%ANSWER%}=={n} (goto :no)
:yes
SET /P i=Enter input file name (e.g blast.k)
SET /P n=Enter number of CPUs (e.g. 2)
SET /P m=Enter memory (e.g 500m)
FOR /D %%D IN (run*) DO (
echo %%D
cd %%D
set lstc_license=network
set lstc_license_server=###.##.##.##
::the solver reference may need to be changed as we move on to new versions
c:\LSDYNA\program\ls971_s_R5.1.1_winx64_p.exe i=%i% ncpu=%n% memory=%m%
cd ..
)
exit /b
:no
exit /b
Our network licensing for LSDYNA allows for queuing of jobs, so ideally I would like to run through the entire loop and have the jobs run simultaneously rather than run one after another. I think this would be possible if I could send each iteration of the loop to a new command window and have it execute independently while the loop in batch script continues.
I'm not sure if I am searching for the wrong things, or if this is a unique request, but I have not been able to find anything that really helps with what I am trying to do. I have tried various things using start /b cmd /k, but I have not been able to pass the loop commands to the new window and have the loop continue in the original window. I have managed to get the new window to open, but not to actually execute any commands, and the code does not continue until the new window is closed.
I would appreciate any suggestions that you might have for how to accomplish my goal.
Thank you!
This starts each command in it's own process, with the start "" at the beginning.
start "" c:\LSDYNA\program\ls971_s_R5.1.1_winx64_p.exe i=%i% ncpu=%n% memory=%m%

Batch run script when closed

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

Does a bat file know its name and can it delete itself

At some point in my script, I'd like the bat script to delete itself. This requires that the script know its name and then to use that name to delete itself. Is this possible?
None of the existing answers provide a clean way for a batch file to delete itself and exit without any visible error message.
Simply including del "%~f0" does delete the script, but it also results in an ugly "The batch file cannot be found." error message.
If it is OK for the script to close the parent CMD process (the console window), then the following works fine without any error message:
del "%~f0"&exit
But it is a bit more complicated if you want the script to delete itself and exit without closing the parent CMD process, and without any error message.
Method 1: Start a second process that runs within the same console window that actually performs the delete. The EXIT /B is probably not necessary, but I put it in to maximize the probability that the batch script will close before the STARTed process attempts to delete the file.
start /b "" cmd /c del "%~f0"&exit /b
Method 2: Create and transfer control to another temp batch file that deletes itself as well as the caller, but don't use CALL, and redirect stderr to nul.
>"%~f0.bat" echo del "%~f0" "%~f0.bat"
2>nul "%~f0.bat"
If I'm not mistaken, %0 will be the path used to call the batch file.
Tested and working:
del %0
exit
%0 gives you the relative path the from the directory where the bat file was started. So if you call it
mybats\delyourself.bat tango roger
%0 will contain mybats\delyourself.bat
del %0 works if you haven't changed your current directory.
%~f0 exapnds to the full path to the file.
For me it was important, that I have no errorLevel 1 after I exited the batch file. I found an suitable and easy answer this way:
DeleteMyself.cmd:
START CMD /C DEL DeleteMyself.cmd
Test batch if DeleteMyself.cmd is returning errorLevel 0. TestDeleteMyself.cmd:
call DeleteMyself.cmd
echo Errorlevel: %errorLevel%

Resources