So basically I have a .bat that is inside my System32 folder.
This batch file accepts a parameter input, this input is a file.
I wanted it to be that I could open my Command Prompt, and for example do
batchfile text.txt
And it would pass test.txt into batchfile.bat. Obviously for my terminal to do this it needs to be in System32.
That is where my issue is. Because the batch file is in System32, when executing the command, it changes my directory to System32.
However the parameter I give it is a file. And when the command is executed and it changes the directory to System32, obviously it can no longer access the file.
How can I get around this?
Before you change directories, expand the filename to its fully-qualified filename and then reference it that way:
#echo off
for %%F in (%1) do set USR_REQFNM=%%~dpnxF
C:
cd \Windows\System32
echo The requested file is "%USR_REQFNM%"
goto ENDIT
REM Cleanup
:ENDIT
set USR_REQFNM=
Related
I am trying to iterate files in a folder and process them with another batch file inside the do loop. It works with echo but as soon as I use the variable as input to the program, it echoes the () part and everything inside.
Here's what I'm trying to do.
#echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
for /r %%f in (/folder/*) do (
set name="%%~nf"
echo !name! <--- ok
process.bat !name! <--- echoes () and commands inside this do loop
)
ENDLOCAL
The process.bat just capitalizes the first letter of the filename and echoes it for debug or confirmation.
A batch file must be called from within a batch file using command call as otherwise Windows command processor continues processing on other batch file with never returning back to initial batch file.
See also: How to call a batch file that is one level up from the current directory?
Please read excellent answer on batch file echo on/off not working properly written by dbenham for the reason on getting suddenly the commands executed by FOR output after first execution of process.bat without using command CALL. I cannot explain better what happens in this case.
The directory separator on Windows is the backslash character \ and not the forward slash / as on Linux or Mac. Windows supports also / in file/folder paths for compatibility reasons by automatically replacing all / by \ before accessing the Windows file systems, but a good written script uses 100% correct syntax and does not depend on automatic corrections done by other programs. / is used on Windows mainly for command line switches.
The usage of / instead of \ can result in an unexpected behavior. For example run a batch file with following content:
#echo off
echo Files in directory %SystemRoot:\=/%/:
for %%I in (%SystemRoot:\=/%/*) echo %%I
echo/
pause
echo/
echo Files in directory %SystemRoot%\:
for %%I in (%SystemRoot%\*) echo %%I
echo/
pause
The first FOR using C:/Windows/* as wildcard pattern outputs the file names with just drive letter + colon + file name + file extension. The file path \Windows\ is missing in output file names. The second FOR loop using C:\Windows\* as wildcard pattern outputs the full qualified file names, i.e. drive letter + colon + file path + file name + file extension.
A file/folder path starting with \ references a directory or file relative to root directory of current DRIVE.
This is explained by the Microsoft documentation Naming Files, Paths, and Namespaces.
It looks like folder is a subdirectory in directory of the executed batch file. In this case / or \ at beginning of folder path is definitely not correct. The backslash at beginning can be omitted or .\ is used to reference the directory folder in current directory on execution of the batch file. But the current directory on batch file execution can be also different to directory containing the executed batch file, for example on running the batch file as administrator, or on running the batch file as scheduled task, or on running the batch file from a network resource accessed using a UNC path. For that reason it is advisable to reference explicitly subdirectory folder in directory of the batch file.
Delayed environment variable expansion is not needed as long as the file name assigned currently to the loop variable does not need to be modified other than the modifiers of for support it. A command line like set name="%%~nf" does not work correct with enabled delayed expansion and file name contains one or more ! because of cmd.exe interprets the exclamation mark(s) in file name as beginning/end of a delayed expanded environment variable reference.
See also: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
It looks like a recursive search for non-hidden files is not really needed as otherwise passing just file name without path and file extension would be not enough to get the right file processed by other batch file process.bat.
So the entire task can be done most likely also with:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%I in ("%~dp0folder\*") do call "%~dp0process.bat" "%%~nI"
endlocal
But if the other batch file process.bat expects that the passed file name without file extension and path is in current directory on execution of process.bat, it is necessary to make the subdirectory folder in directory of this batch file first the current directory.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0folder"
for %%I in (*) do call "%~dp0process.bat" "%%~nI"
popd
endlocal
Note: The batch file folder path referenced with %~dp0 always ends with a backslash. Therefore no additional backslash should be used on concatenating this path string with a file/folder name to avoid having finally on execution of the batch file \\ in full qualified file/folder name, although Windows kernel corrects such paths also automatically by removing second backslash in this case.
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 /?
echo /?
endlocal /?
popd /?
pushd /?
set /?
setlocal /?
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.
I have a batch file in c:\test.bat. The command in this batch file is:
C:
CALL test.bat
Inside my test.bat I have:
\Tables\batch.bat
The command line calls test.bat just fine, but when it gets to the the command \Tables\batch.bat it says:
The system cannot find the path specified.
If I change test.bat to the following it works just fine:
CD Tables
CALL batch.bat
But I can't change test.dat for other reasons. Is there a way to call the test.bat and make sure that my directory is the Tables directory? Test.dat has more than one command, so there is another one for \Sprocs\test2.bat
\Tables\batch.bat means file batch.bat is in a subdirectory Tables in root of current drive.
.\Tables\batch.bat or just Tables\batch.bat means file batch.bat is in a subdirectory Tables of current directory.
..\Tables\batch.bat means file batch.bat is in a subdirectory Tables of parent directory of current directory. In other words Tables is a directory parallel to current directory.
Therefore follow the advice of Liturgist and remove first \ to reference the file batch.bat in subdirectory Tables in current directory.
By the way:
C: switches the current drive to drive C:. But this does not define which directory is the current directory on drive C:. Use the following command to make a specific directory the current directory on drive C: independent on what is currently the current drive and current directory.
cd /D "C:\Path\To\Directory"
In case of batch file is also running and the directory containing the batch file should become the current directory use:
cd /D "%~dp0"
or
pushd "%~dp0"
For details on those two commands, open a command prompt window and run from within the window cd /? and pushd /? to get help for those two commands displayed. call /? explains %~dp0 (drive and path of argument 0 - the batch file).
I am writing a batch file that uses some of the files within it's parent directory (lets say Folder1).
C:\User\Steve\Foder1\
Now I want to make the whole Folder_1 relocatable so that I can copy paste the folder anywhere on my/someone else's computer and run batch script.
D:\User\Random_guy\Folder1\
The question is how do I start batch file's command prompt to (D:\User\Random_guy\Folder1) it's parent directory without writing another batch script to do that.
Start your batch file with:
pushd %~dp0
That will set the current directory to be the folder containing the batch file. Then in the batch file, make sure all your paths are relative to the current directory.
However, if your batch file changes to other directories in the course of its execution and you would still like to be able to refer to the batch's home folder's contents without knowing the exact path, use the same %~dp0 as the path to the file(s) you want to use. For instance, a FileA from the same folder as the batch file would be addressed as
"%~dp0FileA"
Note the absence of a \ before the FileA. This is because the %~dp0 already includes a trailing \ and so the entire thing will evaluate to a correct path all right. (Although if you do put another backslash, like "%~dp0\FileA", it should work as well, because Windows usually disregards multiple consecutive backslashes when in the middle of a path.)
%CD% in a batch file gets the current directory/directory batch is being run in.
So - if I've got this right, you want to run
`C:\steve\folder1\yourbat.bat`
which should copy C:\steve\somefiles to D:\Random_guy and set the current directory to D:\Random_guy\folder1 ?
#ECHO OFF
SETLOCAL
SET subdir=folder1
SET destdir=%~1
IF NOT DEFINED destdir ECHO Require destination username&GOTO :EOF
SET destdir=%~1\%subdir%
:: Ensure destination exists
ECHO MD "%destdir%" 2>nul
SET "sourcefrom=%~dp0.."
ECHO COPY "%sourcefrom%\filestocopy" "%destdir%\..\"
ECHO CD /d "%destdir%"
Note that the MD, COPY and CD commands are merely ECHOed, you'd need to remove the ECHO keyword to execute them.
Run the batch with a parameter of D:\Random_guy
I wrote this script to first install the msi and then copy my application to a temporary directory. But none is working. When the windows.bat file is executed it failed to find package\ and also dist directory
1) User downloaded and execute the windows.bat file which has following tree:
C:\Users\Username\Downloads\windows.bat
C:\Users\Username\Downloads\package\<.msi files>
C:\Users\Username\Downloads\dist\<application files>
2) windows.bat contain below:
msiexec /I "package\files.msi" /qb
set temp=%TEMP%
echo %temp%
xcopy dist %temp% /e /h /R
All fails, to run with windows.bat file. What am i doing wrong?
You need to add the following line to the beginning of your batch file:
cd c:\users\username\downloads
alternatively, you can do this:
cd /d %~p0
%~p0 will take argument #0 (the full path to the batch file) and extract the path from it. The /d option will make sure to also change the current drive if the given path contains a drive specification.
Ok, think I know what's wrong. msiexec.exe runs from the Windows System folder (e.g. C:\Windows\Systeme32) so when you pass it the name of the msi file to install, you need to include the full path to it.
So, using #MikeNakis' info about getting the current path within the batch file, try this (slight tweak to use %~dp0 for just the directory, so not including the batch file name too):
msiexec /I "%~dp0\package\files.msi" /qb
Ensure you are in the correct directory to start off with
CD /d c:\users\%USERNAME%\downloads
As the first line in your batch file