Search code examples
windowsbatch-filerelative-pathabsolute-path

Resolve absolute path from relative path and/or file name


Is there a way in a Windows batch script to return an absolute path from a value containing a filename and/or relative path?

Given:

"..\"
"..\somefile.txt"

I need the absolute path relative to the batch file.

Example:

  • "somefile.txt" is located in "C:\Foo\"
  • "test.bat" is located in "C:\Foo\Bar".
  • User opens a command window in "C:\Foo" and calls Bar\test.bat ..\somefile.txt
  • In the batch file "C:\Foo\somefile.txt" would be derived from %1

Solution

  • In batch files, as in standard C programs, argument 0 contains the path to the currently executing script. You can use %~dp0 to get only the path portion of the 0th argument (which is the current script) - this path is always a fully qualified path.

    You can also get the fully qualified path of your first argument by using %~f1, but this gives a path according to the current working directory, which is obviously not what you want.

    Personally, I often use the %~dp0%~1 idiom in my batch file, which interpret the first argument relative to the path of the executing batch. It does have a shortcoming though: it miserably fails if the first argument is fully-qualified.

    If you need to support both relative and absolute paths, you can make use of Frédéric Ménez's solution: temporarily change the current working directory.

    Here's an example that'll demonstrate each of these techniques:

    @echo off
    echo %%~dp0 is "%~dp0"
    echo %%0 is "%0"
    echo %%~dpnx0 is "%~dpnx0"
    echo %%~f1 is "%~f1"
    echo %%~dp0%%~1 is "%~dp0%~1"
    
    rem Temporarily change the current working directory, to retrieve a full path 
    rem   to the first parameter
    pushd .
    cd %~dp0
    echo batch-relative %%~f1 is "%~f1"
    popd
    

    If you save this as c:\temp\example.bat and the run it from c:\Users\Public as

    c:\Users\Public>\temp\example.bat ..\windows

    ...you'll observe the following output:

    %~dp0 is "C:\temp\"
    %0 is "\temp\example.bat"
    %~dpnx0 is "C:\temp\example.bat"
    %~f1 is "C:\Users\windows"
    %~dp0%~1 is "C:\temp\..\windows"
    batch-relative %~f1 is "C:\Windows"
    

    the documentation for the set of modifiers allowed on a batch argument can be found here: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/call