Search code examples
windowsbatch-filecmd

Can't run as Admin


I have to execute the ewfmgr.exe which can be executed only when the Command window is opened as an Admin.

If I go to Start->type cmd.exe->Right click->Run as Administrator then the following Comand prompt windows appear. In this window, if I write ewfmgr.exe (which the EXE file that I have to execute), then the command is executed without any problem.

image

MY REQUIREMENT: My requirement is to execute the command through a script file (RunasAdmin.cmd file) and this script file will be executed through an NSIS Installer.

Since, the ewfmgr.exe can be executed only with Admin, so I have to escalate my script to get Admin rights. For this, I have the following script:

Script to Get Admin Right: "(RunasAdmin.cmd)"

::::::::::::::::::::::::::::::::::::::::::::
:: Elevate.cmd - Version 4
:: Automatically check & get admin rights
::::::::::::::::::::::::::::::::::::::::::::
 @echo off
 CLS
 ECHO.
 ECHO =============================
 ECHO Running Admin shell
 ECHO =============================

:init
 setlocal DisableDelayedExpansion
 set cmdInvoke=0
 set winSysFolder=System32
 set "batchPath=%~0"
 for %%k in (%0) do set batchName=%%~nk
 set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
 setlocal EnableDelayedExpansion

:checkPrivileges
  NET FILE 1>NUL 2>NUL
  if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )

:getPrivileges
  if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
  ECHO.
  ECHO **************************************
  ECHO Invoking UAC for Privilege Escalation
  ECHO **************************************

  ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
  ECHO args = "ELEV " >> "%vbsGetPrivileges%"
  ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
  ECHO args = args ^& strArg ^& " "  >> "%vbsGetPrivileges%"
  ECHO Next >> "%vbsGetPrivileges%"

  if '%cmdInvoke%'=='1' goto InvokeCmd 

  ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
  goto ExecElevation

:InvokeCmd
  ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
  ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"

:ExecElevation
 "%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
 exit /B

:gotPrivileges
 setlocal & pushd .
 cd /d %~dp0
 if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul  &  shift /1)

 ::::::::::::::::::::::::::::
 ::START
 ::::::::::::::::::::::::::::
 REM Run shell as admin (example) - put here code as you like
 ewfmgr c: -enable
 pause
 cmd /k

PROBLEM: If I execute the script (RunasAdmin.cmd) just by double clicking on it, the script is executed and get the task done without any error. But if I execute the script (RunasAdmin.cmd) through my NSIS installer (EWFMGR_Run.exe) then, I get an error that ewfmgr is not recognised as an internal or external command

NSIS Installer Code: (EWFMGR_Run.exe)

OutFile "EWFMGR_Run.exe"
section
    ExecWait "D:\Disk\RunasAdmin.cmd"
sectionEnd

The Command window opened by NSIS installer after running the script (RunasAdmin.cmd) is following:

image

Queston: Both the command windows are opened as Admin and are into the same working directory. But how come the window opened by NSIS installer is not able to find ewfmgr.exe?

UPDATE-1: Bascially the problem is in the CMD window opened by the NSIS installer. Even if I move to the path C:\Windows\System32 manually using cd /D C:\Windows\System32 and try to execute ewfmgr.exe (which is available in that path), CMD does not recognize it.

References: The script file to elevate to Admin has been taken from Matt's answer given here.


Solution

  • Try modifying RunasAdmin.cmd to use Sysnative instead of System32:

    set winSysFolder=Sysnative

    I am guessing that EWFMGR_Run.exe is launching a 32 bit cmd window and windows is forcing the c:\windows\syswow64 override on your attempted override of set winSysFolder=System32

    According to this article, you should be using the Sysnative virtual folder instead.

    The 'Sysnative' folder

    As explained above, accessing the 64-bit System32 folder from a 32-bit application by simply inserting "\System32" in the folder path is not possible. A redirection to the SysWOW64 folder is made automatically by the system if you try that. But there is another folder name that can be used instead: Sysnative.

    Sysnative is a virtual folder, a special alias, that can be used to access the 64-bit System32 folder from a 32-bit application or script. If you for example specify this folder path in your application's source code:

    C:\Windows\Sysnative

    the following folder path is actually used:

    C:\Windows\System32