call command for bat script not working - windows

Essentially I have two .bat scripts that work just fine individually, however I wanted to combine the two scripts into one action as i have it assigned to a hotkey and want all of this with one press of a key, not two but am having problems because the scripts are in different directories.
Below are my two scripts:
BLAH-Script.bat
RE4_UHD_BLAH_Tool.exe -p
DEL /F /S /Q /A "F:\r101\r101_09.AEV"
and the second script:
UDAS_TOOL.bat:
DEL /F /S /Q /A "F:\st1\rl01.udas"
ping -n 1 localhost
DEL /F /S /Q /A "F:\UDAS Tool\r101.udas"
UDAS_Tool.exe -p
Now, both of these work great on their own because each of the scripts calls on an .exe that is in the same DIR as the script that calls them, but trying to get them into one .bat file has not worked using the CALL function because one of the scripts exists in an outside directory.
I have tried to make a new .bat script that would execute both bat scripts in one:
call "F:\pack\BLAH-Script.bat"
ping -n 1 localhost
call "F:\pack\UDAS\UDAS_TOOL.bat"
However this does not work.The files are not packaged by the exe tools as intended.
To try and figure out the problem I added pause command between scripts:
call "F:\pack\BLAH-Script.bat"
pause
call "F:\pack\UDAS_TOOL.bat"
This command allowed me to read the output before the window was closed and yielded the culprit. In the first script I am getting the following error:
F:\UD - r101-->RE4_UHD_BLAH_Tool.exe -p
'RE4_UHD_BLAH_Tool.exe' is not recognized as an internal or external command,
operable program or batch file.
I believe what is happening it that each file works fine if run in its own directory because they are in the same DIR as the .exe they are calling, but the first .bat file will not execute because the third bat file ( the one that is that is calling the first & second) is not in the same DIR as the first.
I have tried:
CD /D "F:\pack"
call "F:\pack\BLAH-Script.bat"
pause
CD /D "F:\pack"
call "F:\pack\UDAS\UDAS_TOOL.bat"
with the same error.
How do I get the directories sorted out ?

In theory, you could simply fully-qualify the executable path, or make sure that the executables are located on the path.
However, some programs assume that the executable is in the current directory, and expect that configuration files, etc. are similarly in that directory, so what I'd do is
in each batch, after the initialisation ceremony (#echo off/setlocal...) add a
pushd "actualexcutablelocation"
and ensure that on exit from the batch,
popd
is executed to restore to the original directory.
pushd switches current directory to the nominated directory until a popd is executed to return to the original.

Related

I'm trying to use Robocopy to replace a cmd file

I've created a cmd file which uses the Robocopy command to update some files on the PC, but I can't replace the cmd files, because this contains the Robocopy script which is doing the updating. How do you replace a file which is doing the replacing?
I've moved the cmd file to another directory, which allows me to update most of the files, but I still can't replace the cmd file.
The Flags I'm using in Robocopy are /MIR /Copy:DAT /DCOPY:T
The Robocopy stopped at the cmd file and I can't replace it.
I don't see any reason for %SystemRoot%\System32\robocopy.exe failing to copy the batch file currently processed by cmd.exe than this batch file is additionally opened in an application like a text editor which prevents write access and deletion of the file as long as it is opened in the application.
However, the following code added to your batch file with unknown content could solve the problem.
#echo off
if /I not "%~dp0" == "%TEMP%\" (
copy /Y "%~f0" "%TEMP%" >nul 2>&1
if exist "%TEMP%\%~nx0" (
set "CurrentDirectory=%CD%"
set "InitialExecution=%~dp0"
cd /D "%TEMP%"
"%TEMP%\%~nx0" %*
)
)
rem Insert here other commands to execute by the batch
rem file now running from directory of temporary files.
rem The next three commands are only for demonstration.
if defined CurrentDirectory echo Initial current directory: %CurrentDirectory%
if defined InitialExecution echo Initial execution path: %InitialExecution%
pause
set "InitialExecution="
if defined CurrentDirectory set "CurrentDirectory=" & cd /D "%CurrentDirectory%" 2>nul & (goto) 2>nul & del "%~f0"
This batch file first checks if it is started from directory for temporary files. This is not the case on double clicking on the batch file, except the batch file is stored by chance in directory for temporary files by the user and double clicked on it in this directory. If batch file is not stored in directory for temporary files, it does following:
The batch file copies itself to directory of temporary files (only read access).
It verifies if the file copy was really successful which should be always true.
It defines two environment variables with path of current directory and initial execution path for later usage.
It sets the current directory to directory for temporary files.
This makes it possible to even delete the directory containing batch file on batch file directory being also current directory as typical on double clicking on a batch file stored on a local drive executed by current user.
The batch file runs itself from within directory for temporary files with passing all arguments passed to the batch file on initial execution further on its copy.
The Windows command processor cmd.exe executing the batch file continues batch file processing on its copy in temporary files directory with first line #echo off returning never to the initial batch file as started by the user.
Now with batch file processing done on a copy of initial batch file in temporary files directory and with current directory being also the directory for temporary files, the other commands in batch file can do everything in initial current directory respectively initial execution directory of the batch file like updating the files in these directories or even deleting these directories temporarily or permanently.
The three comment lines with command rem and the next three lines just demonstrate what can be done here and how to use the environment variables set by the batch file on initial execution. The two environment variables do not exist (most likely) on batch file being initially stored in directory for temporary files and executed by the user from this directory.
The batch file deletes the environment variable InitialExecution independent on its existence to restore initial environment in case of batch file executed from within a command prompt window.
Finally with batch file initially not executed from temporary files directory it deletes also the environment variable CurrentDirectory, changes the current directory back to initial current directory, if that directory still exists, and deletes itself from directory for temporary files.
(goto) 2>nul & del "%~f0" for batch file deletion without any error message output by Windows command processor was copied by me from Dave Benham's answer on How to make a batch file delete itself?
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.
call /? ... explains %~dp0, %~f0 and %~nx0
cd /?
copy /?
del /?
echo /?
goto /?
if /?
pause /?
set /?
See also the Microsoft article about Using command redirection operators.

Force batch file to load to RAM before running

I have a batch file in an administrative partition of my portable drive, with a shortcut symlinked to it on the root of the drive. The purpose of the file is to unmount the drive and remount it as the specified letter (mostly for convenience).
When the file is opened, it is opened relative to the current letter rather than to the volume ID, so naturally, when the unmount happens, the command processor has no idea what to do next as it reads the file as needed rather than caching it.
There are two foreseeable solutions that I can think of but can't figure out:
Make the file get cached into RAM before executing
Make the file run relative to the volume ID instead of the mountpoint (tried using {VOLID}\file where {VOLID} is the volume ID, but it couldn't find the file although it was there (navigating to {VOLID}\ correctly opened the directory, but trying to open the file didn't correctly open the file.
Despite of the other answers, it's trivial to cache a whole batch script to RAM.
You only need to build a single block, as blocks are parsed and cached before they can be executed.
But blocks have some drawbacks, percent expansion doesn't work, therefore you need to use delayed expansion.
call and goto can't be used, as they would try to read from the file again.
(goto) 2>nul & (
echo The script is started
REM Need to change the directory, else the unmount doesn't work
c:
mountvol e: /p
mountvol g: \\?\Volume{VOLID}\
dir G:\
echo The script will end now
REM Here you need the goto 2>nul hack to avoid an error message
)
The (goto) 2>nul & seems strange here, but it's explained at SO:How to make a batch file delete itself?.
It works also without the goto, but then the scripts ends with an error message
Have the batch file determine where it is running from see this. If it's running from the portable drive have it make a copy of itself to a permanent drive location (c:\temp for instance) then run that copy of the batch file.
When running a bath file there is no concept of running it from RAM. Windows command processor will always go back to the .bat file for the 'next' command to run. If you edit a batch file while it's running the command processor will pick up your changes.
JJF wrote already the correct answer. It is not possible to copy a batch file to RAM and inform Windows command interpreter to interpret the command lines in memory. It would be possible to create a RAM disk, copy the batch file to the RAM disk and run it from there. But this just makes the task more complicated than necessary.
This commented batch code demonstrates how to copy a batch file to directory for temporary files and start it there for complete processing in a separate Windows command process.
#echo off
rem Is the batch file path not the path of directory for temporary files?
if /I not "%~dp0" == "%TEMP%\" (
rem Copy the batch file to directory for temporary files.
copy "%~f0" "%TEMP%" >nul
rem Run the copy in a separate command process with name of the batch
rem file with extension as window title and exit this batch process.
start "%~nx0" "%TEMP%\%~nx0"
goto :EOF
)
echo The batch file is now running from directory for temporary files.
echo.
pause
rem Delete the batch file in directory for temporary files
rem and exit the command process started for this batch file.
del "%TEMP%\%~nx0" & exit
Replace the two echo commands and the pause command by your batch code.
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.
call /? ... explains %~dp0 (drive and path of argument 0 which is the batch file itself) and %~nx0 (name and extension of batch file)
copy /?
del /?
echo /?
exit /?
goto /?
if /?
pause /?
rem /?
start /?
See also answer on Single line with multiple commands using Windows batch file for an explanation of operator & used here two run the two commands del and exit read from one line to avoid an opened console window with an error message as batch file deleted unexpected for the Windows command interpreter while processing it.

Write a batch file to do call another batch file and install a program

I am having trouble with a batch file. I have 2 files the first batch file runs and it creates the directory and copies the files needed. It appears to call the second batch file correctly because it opens the instructions.txt but then it stops. I will be running the first batch file from a CD and then the dbinstall.bat from the C:\testing folder.
this is my setup.bat
#echo off
md "C:\testing"
xcopy *.* C:\testing
CALL "C:\testing\dbinstall.bat"
Which in turns should call and run this
REM ***PLEASE REPLACE %DWVerFileName.exe WITH THE PROPER VERSION OF THE EXE FILE***
REM ***MAKE SURE THE 7z FILE INCLUDES THE CUSTOMER NAME AND THEN CHANGE %filename%.7z TO THE FILE NAME***
CALL "C:\testing\Instructions.rtf"
start /b /wait "C:\testing\7z423.exe"
SET AppExePath="%ProgramFiles(x86)%\7-zip\7z.exe"
IF NOT EXIST %AppExePath% SET AppExePath="%ProgramFiles%\7-zip\7z.exe"
%AppExePath% e database.7z
start /b /wait "setup.exe"
SQLCMD -E -S touch -Q "RESTORE DATABASE testing FROM DISK='C:\testing\database.bak'"
I am stuck and any help would be appreciated. Thanks
Since we have no idea of what "it stops" means, or where "it stops", I'd guess
CALL "C:\testing\Instructions.rtf"
should be
start "instructions" "C:\testing\Instructions.rtf"
which would then invoke whatever program is associated with .rtf, no doubt dislaying the instructions and keeping the displaying mechanism open while the 7z423 executable runs.

Self-deleting batch file to delete a directory not fully deleting and not exiting on Windows 7

At uninstall time I run an executable to create a self-deleting batch file to do some directory cleanup. It always works great and has been for years.
I have run into a case where I need to do something similar to do some cleanup at install time. I have a different .Net console app that creates and runs a batch file that I am launching from setup.exe generated by InstallShield 2013. Here is the sequence of events:
Installer creates a directory and extracts some files, one of which is setup.exe.
An exe is run that ultimately runs setup.exe.
Setup.exe does the installation and just before exit I call LaunchApp to run my console app, DirectoryDelete.exe, with the directory to delete as an argument.
DirectoryDelete.exe creates a batch file in the parent directory of the directory to delete and runs it.
For example the resulting command line is:
DirectoryDelete.exe -dir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp"
The resulting batch file is:
#echo off
:repeatExe
del "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe"
if exist "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe" goto repeatExe
:repeatDir
rmdir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp" /s /q
if exist C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\nul goto repeatDir
del %~F0&exit
So, basically the batch file waits on setup.exe to finish, then quietly deletes the directory, then itself.
However, what is happening is the contents of the directory get deleted, but neither the directory nor the batch file get deleted. It looks like the batch file is stuck in a loop - likely blocking itself. When I try to delete the directory myself (command line or explorer), it says another process is using it (the cmd.exe of the batch file). If I try to re-run the batch file, it is busy. If I kill the cmd.exe, then I can manually clean up.
Since this technique works so well at uninstall time, I am pretty confused about why it is not working during my cleanup at install time. Everything is running with elevated privileges. My best guess is it has to do with the context - the console application being launched from setup.exe.
Any help or ideas would be greatly appreciated.
EDIT:
I got the batch file to exit and delete itself, but the directory still did not get deleted. I modified the batch file by adding a few of lines:
#echo off
:repeatExe
del "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe"
if exist "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe" goto repeatExe
:repeatDir
if not exist "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\DeleteDirectory.exe" goto cleaned
rmdir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp" /s /q
if exist C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\nul goto repeatDir
:cleaned
rmdir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp" /s /q
del %~F0&exit
My idea was to look for another file I knew was there. If it had been deleted, then I know the rmdir did part of its work. That way I could at least break the loop and take another shot at removing the directory, then clean up and get out.
What I learned there is that the rmdir is failing, thus creating an infinite loop in the original bat file. Now, if I run the batch file myself, even on a directory created by the install process, everything works fine....
For rmdir /s to not work would mean a file is in use, a file is locked or a permissions problem. Could there also be confusion about working directory?
I figured out what the problem was: The rmdir /s was failing because the current directory was set to the directory I was trying to delete. Apparently that is not the case during the uninstall operation.
I changed my batch file to move up to the directory DeleteDirectory.exe is launched from:
#echo off
pushd "%~dp0"
:repeatExe
del "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe"
if exist "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe" goto repeatExe
:repeatDir
rmdir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp" /s /q
if exist C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\nul goto repeatDir
del %~F0&exit
Works fine now.

How would I run a batch program from another batch program within its own environment?

I need to run a batch file located in another folder that must be called from another batch file.
Whenever I do call this batch file from the first, let's call them Batch_A and Batch_B, respectively, the second tries to run from the directory of the first batch file.
Batch_A needs to call or start Batch_B, however Batch_B needs to run as if I were to manually double-click it myself.
This is what I currently have at the end of my first batch
start "A thing" "%output%\thing.bat" /b
Have you looked into push or pop.
Before calling the second batch file, enter the "push" command:
pushd %dynamicdirectory%
Call batchfileb.bat
popd
If Batch_B is designed/written to be always run from the direcory where it is located
you might also consider to modify Batch_B.bat
setlocal
cd /D %0\..
REM your original content
endlocal
In %0 the path to the batchfile is stored.
The trick is to assume %0 is a directory then to change one level lower
based on that diretory.
With /D also the drive letter is changed correctly.
The cd command doesn't care if %0 is really a directory.
In fact %d doesn't even have to exist (%0\dummy\..\.. would also work).
The setlocal command is to have the working directory beeing restored
when Batch_B.bat has finished.
I noticed that the endlocal command is not really necessary
in this context since it is applied imlicitely when Batch_B finishes.

Resources