How can I keep the working directory of the invoker (outer) batch file, for the invoked (nested/inner) batch file?

0

1

Let me explain what did I mean.

I run cmder.exe (via init.bat) inside a cmd.exe console window. See the attached GIF. For this purpose I wrote a little batch script cmr.bat shown below. It does work as it meant to.

@echo off
%comspec% /k "C:\cmder\vendor\init.bat %*"
EXIT /B %ERRORLEVEL%

enter image description here

But, this approach doesn't provide the ability to run the init.bat in elevated mode directly.

Being inspired by the given solution, I created another batch file amr.bat in order to run the inner init.bat in elevated mode.

Here is the content of the amr.bat

:: Automatically check & get admin rights V2
@echo off
:: BatchGotAdmin
::-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params = %*:"="
    echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    del "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    pushd "%CD%"
    CD /D "%~dp0"

::::::::::::::::::::::::::::::
:: START OF USER CUSTOM CODE
::::::::::::::::::::::::::::::

%comspec% /k "C:\cmder\vendor\init.bat %*" rem THIS IS MY CODE
EXIT /B %ERRORLEVEL%

The amr.bat does run the init.bat in the elevated mode, but doesn't keep (retain) the working directory from which it has been called. The below GIF screencast demonstrates this behavior.

enter image description here

The init.bat didn't receive the working directory from which it was invoked. Instead init.bat was started with the working directory set to the location of the amr.bat (which resides in C:\BatScripts directory).


So my question is, how can I modify the amr.bat script, in order to keep (retain) the current directory from which it was invoked?

Any ideas?

AlexMelw

Posted 2017-11-10T18:33:32.603

Reputation: 121

Answers

0

The solution wasn't obvious for me, however it was much simpler than I expected it to be.

Being driven by this hint, I've realized that the current context (working directory of the invoker batch file) had to be captured and passed to the VBScript file.

I've modified my amr.bat script in the following way.

@echo off

:: Let me capture the current working directory
set InvokerCapturedWorkingDirectory=%cd%

:: BatchGotAdmin
::-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params = %*:"="
    echo UAC.ShellExecute "%comspec%", "/k C:\cmder\vendor\init.bat %params% & cd /d %InvokerCapturedWorkingDirectory%", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    del "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    pushd "%CD%"
    CD /D "%~dp0"

:::::::::::::::::::::::::::::::
:: START OF USER CUSTOM CODE ::
:::::::::::::::::::::::::::::::

:: IS NOT NEEDED ANYMORE
::%comspec% /k "C:\cmder\vendor\init.bat %*"
EXIT /B %ERRORLEVEL%

Let me confirm my words:

enter image description here


If you are curious about the content of the generated VBScript file (which runs the batch file in elevated mode), here you are:

enter image description here

AlexMelw

Posted 2017-11-10T18:33:32.603

Reputation: 121