I am learning Windows PowerShell and I am struggling with the very basic task, how to create a .bat file to change the current directory? The simple .bat file with cd mydir
inside worked well using cmd.exe
, but it does not work in PowerShell:
PS C:\Users\ET\test> dir
Directory: C:\Users\ET\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 01/10/2021 10:57 mydir
-a---- 01/10/2021 10:58 10 changeDir.bat
PS C:\Users\ET\test> type changeDir.bat
cd mydir
PS C:\Users\ET\test> .\changeDir.bat
C:\Users\ET\test>cd mydir
PS C:\Users\ET\test>
You see that my current directory has not changed after executing the .bat file.
Works as expected using cmd.exe
:
C:\Users\ET\test>changeDir
C:\Users\ET\test>cd mydir
C:\Users\ET\test\mydir>
CodePudding user response:
Because a batch file (.bat
, .cmd
) runs in a child process (via cmd.exe
), you fundamentally cannot change PowerShell's current directory with it.
- This applies to all calls that run in a child process, i.e. to all external-program calls and calls to scripts interpreted by a scripting engine other than PowerShell itself.
- While the child process' working directory is changed, this has no effect on the caller (parent process), and there is no built-in mechanism that would allow a given process to change its parent's working directory (which would be a treacherous feature).
The next best thing is to make your .bat
file echo (output) the path of the desired working directory and pass the result to PowerShell's Set-Location
cmdlet.
# Assuming that `.\changeDir.bat` now *echoes* the path of the desired dir.
Set-Location -LiteralPath (.\changeDir.bat)
A simplified example that simulates output from a batch file via a cmd /c
call:
Set-Location -LiteralPath (cmd /c 'echo %TEMP%')
If you're looking for a short convenience command that navigates to a given directory, do not use a batch file - use a PowerShell script or function instead; e.g.:
function myDir { Set-Location -LiteralPath C:\Users\ET\test\myDir }
Executing myDir
then navigates to the specified directory.
You can add this function to your $PROFILE
file, so as to automatically make it available in future sessions.
CodePudding user response:
try the following
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Write-host "running in directory $dir"