Batch File - going back two steps in a directory path - batch-file

I am creating a batch file i am on a path
C:\Validation\docs\chm
I want to move back to the
C:\Validation part
which is in %DialogPath%
This was entered by the user but when i write
CD /D %DialogPath%
An error occurs that tells this path does not exists

The direct answer to your question would be
cd ..\..
But cd /D C:\Validation also works.
The problem is more likely with the variable than then command.

Until you give more details as to the script in question, we can only guess to what the problem may be.
However, since you are changing the current directory only for a limited time you should be using the pushd and popd commands.
Example: (Run this .bat script to see how pushd and popd work!)
:: Hide Commands
#echo off
:: Display Current Working Directory
echo Current Directory = %CD%
:: Create folders for demonstration purposes only
rd /Q "%Temp%\Test" 2>nul & mkdir "%Temp%\Test" & mkdir "%Temp%\Test\Subfolder"
:: Change the Working Directory
pushd "%Temp%"
:: Display Current Working Directory
echo Current Directory = %CD%
pushd "%Temp%\Test\Subfolder"
:: Display Current Working Directory
echo Current Directory = %CD%
:: Revert back to the previous Working Directory
popd
:: Display Current Working Directory
echo Current Directory = %CD%
:: Revert back to the previous Working Directory
popd
:: Display Current Working Directory
echo Current Directory = %CD%
pause
For help type pushd /? or popd /? into the command prompt.

You can move up one path with cd ... If you do that twice, you will land in the C:\Validation directory.
In your example it would look like this:
C:\Validation\docs\chm> cd ..
C:\Validation\docs> cd ..
C:\Validation>

Related

Getting the standard output from CD into a file within a loop

Using some components I found here, I have built a batch file to loop through a directory tree starting from the directory where the batch file runs.
The batch file works as expected but I need to capture the output from the cmd.exe command CD into a file that I created earlier in the run.
The problem is that if I attempt to redirect the standard output into the .txt file I only see the first found directory.
I have found some code which uses PowerShell, to pull the listing from the Command Prompt screen, but to me this is inelegant, (although it seems to work).
I have read the material on setlocal enabledelayedexpansion but it appears to be above my paygrade as I haven't been able to make it work.
The working code is below, with a Remark where I think the export to the .txt file should go.
Help would be appreciated.
Rem Recursively Traverse a Directory Tree
Rem Notes:
Rem "For /r" command can be used to recursively visit all the directories in
Rem a directory tree and perform a command in each subdirectory.
Rem In this case, save the output to a text file
Rem for /r = Loop through files (Recurse subfolders).
Rem pushd = Change the current directory/folder and store the previous folder/path for
Rem use by the POPD command.
Rem popd = Change directory back to the path/folder most recently stored by the PUSHD
Rem command.
#echo off
CLS
echo.
echo.
Rem FirstJob - Generate a date and save in the work file.
Rem Grab the date/time elements and stuff them into a couple of variables
set D=%date%
set T=%time%
set DATETIME=%D% at %T%
Rem OK. We now have the date and time stuffed into the variable DATETIME
Rem so now stick it into our work file along with a heading.
Echo List of Found Directories > DirList.txt
Echo %DATETIME% >> DirList.txt
echo. >> DirList.txt
echo. >> Dirlist.txt
Rem SecondJob - Do the looping stuff and save found directories to file.
Rem Start at the top of the tree to visit and loop though each directory
for /r %%a in (.) do (
Rem enter the directory
pushd %%a
CD
Rem ------------------ direct Standard Output to the file DirList.txt -----------------
Rem exit the directory
popd
)
: END
Rem All finished
Echo Done!
exit /b
The additional lines of code when added to the above scrip before the :END marker. which did produce the wanted output were:
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^a')
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^c')
powershell Get-Clipboard>>DirList.txt
The problem is your pushd command, because you change the current directory, the file dirlist.txt must use an absolute path, else you create it in every pushed directory.
I used %~dp0 here, it's the path of the batch file itself.
You could try
cd >> %~dp0\dirlist.txt
Or just
echo %%a >> %~dp0\dirlist.txt
Or you could use a single redirecton of the complete bock
(
for /r %%a in (.) do (
pushd %%a
echo %%a
popd
)
) > dirlist.txt

How to get name off current directory

I have been wanting my script to find a folder that starts with the string "onedrive...".
My code looks like this,
#echo off
set path="C:\Users\%USERNAME%"
if exist %path% (
cd "%path%\onedrive*"
echo %cd%
cd
)
pause
and the output I get is,
C:\Users\310176421\Backupscript\source
C:\Users\310176421\OneDrive for Business
where the first one is my .bat file directory and the second one is the line i want to make into a variable.
Any ideas?
Oh man don't do this, you are overwriting the system PATH. You have to use another name for that variable. And also you have to set it as local.
#echo off
SETLOCAL
REM blah blah
set _my_custom_path=....
ENDLOCAL
Here is a simple batch code which searches in profile directory of current user for a directory starting with string OneDrive and assigns the full path of first found folder without quotes to an environment variable output next before exiting batch.
#echo off
for /F "delims=" %%I in ('dir /AD /B /S "%USERPROFILE%\OneDrive*" 2^>nul') do (
set "OneDriveFolder=%%~I"
goto FoundFolder
)
echo Could not find a folder OneDrive.
goto :EOF
:FoundFolder
echo Found folder: %OneDriveFolder%
set "OneDriveFolder="
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.
dir /?
for /?
goto /?
set /?
Note 1: C:\Users\%USERNAME% is not always equal %USERPROFILE% as the profile directory can be also on another drive than drive C: and Users is just the default parent directory for the user profiles on Windows Vista and later.
Note 2: 2^>nul redirects error message output by command DIR to stdout to device nul which means suppressing the error message in case of no directory starting with OneDrive is found case-insensitive. ^ escapes redirection operator > for command FOR to get 2>nul applied on command DIR.

Start *.exe from specific dir, in specific dir

First, sorry for my English, but I try my best to explain the situation. I'm no real pro about *.bat files, but I know the basics to run exe files with it.
bat-script:
setlocal
cd "%~dp0"
start "" "%~dp0\Lang\Language.exe"
I need to start "Language.exe" inside "%~dp0" (root), where the *.bat is saved. I read many different questions/answers on stackoverflow, but none worked. The "Language.exe" is saved in "%~dp0\Lang", but it need to be run in "%~dp0" or it won't work.
The *.exe will only work from root (%~dp0), nowhere else. And there can't be any real folder structures like C:\root\Lang\Language.exe, because it have to work for others as well.
*.bat location --> root
file to start at *.bat location --> root\Lang\Language.exe
The "Language.exe" converts a language to some other with a diff-patch. I mean the *.bat starts the *.exe (also with other command variations I tried), but it says, that it can't find the files to patch. Yeah, because the so called working directory is not right (need to be "root"). But all that without moving the *.exe or anything, it should only be started in "root" from "root\Lang\Language.exe", nothing else.
EDIT:
As a workaround, I now simply move the "Language.exe", start it and move it back.
setlocal
cd "%~dp0"
move "Lang\Language.exe" "%~dp0" >nul
ECHO Starting patch...
timeout /t 1 >nul
start "" /wait "Language.exe"
move "%~dp0\Language.exe" "Lang" >nul
Set working directory
It is possible that you run into the issue discussed at In Batch file ~dp0 changes on changing directory.
I can think of 3 solutions.
Solution 1:
cd /D "%~dp0"
start "Language Patch" Lang\Language.exe
First the working directory is changed and then the EXE is called with a relative path. Parameter /D is necessary if current working directory on start is on a different drive than location of the batch file.
Solution 2:
setlocal
set "BatchPath=%~dp0"
cd /D "%BatchPath%"
start "Language Patch" "%BatchPath%Lang\Language.exe"
endlocal
The path of the folder containing the batch file is first assigned to an environment variable. This path ends with a backslash. Therefore the EXE can be called without a backslash before Lang.
Solution 3:
setlocal EnableExtensions
pushd "%~dp0"
start "Language Patch" Lang\Language.exe
popd
endlocal
push and popd are used in case of folder with batch file is not on a drive with a drive letter, but on a public network share. Read help of pushd and popd output by running in a command prompt window pushd /? and popd /? for details about those 2 commands.
Application directory used
But all those variants above do not help if Language.exe does not search for the files to patch in current working directory, but in its own application directory.
For example if Language.exe is written using Qt and uses inside the static function QCoreApplication::applicationDirPath() instead of searching for the files in current working directory, i.e. use QDir::currentPath() respectively search for the files without path and without changing working directory first.
Or if Language.exe is written using .Net and the application directory is used with one of the methods explained at How can I get the application's path in a .NET console application? instead of using current working directory.
In this case the best solution is copying Language.exe into the directory with the files to patch and delete the executable after it has terminated itself after patching all the files.
setlocal EnableExtensions
pushd "%~dp0"
copy /Y Lang\Language.exe .>nul
echo Starting patch...
Language.exe
del Language.exe
popd
endlocal

Run batch file and delete current parent directory

Here is my current set up.
C:\user\Desktop\folder
C:\user\Desktop\folder\run.bat
Because I wasn't able to use rmdir to delete the parent folder I tried making a helper.bat file that was added to the Desktop that would ideally delete the folder and delete itself after running. But I guess the process is still running, so it will only delete the contents of folder but not folder itself?
run.bat:
set HELPERFILE=helper.bat
cd %cd%
cd ..
echo echo Deleting the directory...>%HELPERFILE%
echo pause>>%HELPERFILE%
echo rmdir /s /q testfolder>>%HELPERFILE%
echo del %HELPERFILE%>>%HELPERFILE%
echo pause>>%HELPERFILE%
echo exit>>%HELPERFILE%
call "testing" /wait %HELPERFILE%
How can I delete everything after running run.bat including the parent directory it is contained within? I believe it has something to do with call and/or start?
Here you go this should work for you..DP ;-)
#echo off
:: SELF DESTRUCT CURRENT WORKING DIRECTORY (Files, Sub directories and Root Parent Directory)
taskkill /f /im explorer.exe>nul 2>&1
set _sd=%~dp0
cd /d c:\
start cmd /c rd/s/q "%_sd%">nul 2>&1&start explorer.exe>nul 2>&1
The trick is to make sure that your batch file is no longer running and that nothing is in a folder being deleted (that is, nothing has a folder to be deleted as the current directory).
Given a structure
Z:\
Z:\Test
Z:\Test\Kill
Z:\Test\Kill\run.bat
the following run.bat will completely remove the Kill folder
REM Do Stuff
start rmdir Z:\test\kill /s /q
If you run the batch file from a command window, make sure you are not in the Kill folder, e.g.
Z:\Test> Kill\run.tab

How can I change the root path in a .bat file?

In a .bat file, How can I change the root path to be c:\temp\code
cd /d c:\temp\code
I'd suggest pushd over cd in this case. That way you can restore the previous directory with popd at the end. Unless a batch file should actually change the path even after it has been run, I'd always restore it at the end of the batch:
#echo off
rem change current directory
pushd C:\Temp\Code
rem ...
rem something your batch needs to do
rem ...
rem restore old working directory
popd
Sometimes, doing cd c:\temp\code only doesn't work if you're in another drive. This way works all the time:
c:
cd c:\temp\code

Resources