Search code examples
batch-filedirectoryexe

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

Solution

  • 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