Search code examples
batch-fileshellexecutehybridwsh

Can Window's ShellExecute function accept WSF script arguments?


The batch hybrid script below aims to auto invoke Administrator privileges before running some tasks requiring elevated rights. It does popup the UAC prompt, but regardless of the user choice Admin privileges aren't granted.

I wonder if Window's ShellExecute function used in it can accept WSF arguments or other expandable parameters? In this case its the batch file name. If it can, how the script should be changed for that without restructuring aimed at using a different method?

<!-- : Begin batch script
@echo off
setlocal EnableExtensions EnableDelayedExpansion
CD /D "%~dp0" & echo "%*"
set "dir=%temp%\Unzip"
set "file=%USERPROFILE%\Downloads\archive.zip"
if not "%1"=="ADR" (call :GetAdminRights
    if defined adm cscript //nologo "%~f0?.wsf" //job:ADM "%~nx0")
>nul 2>&1 net file && (echo/ & echo "!errorlevel!") || ^
(echo/ & echo "!errorlevel!" & goto :end)

:: add your code here
echo Performing admin tasks
echo Hello >C:\test.txt

:end
timeout 5
exit /b

:GetAdminRights
REM Check for permissions
>nul 2>&1 net file
REM If error flag set, user don't have admin permissions
if '!errorlevel!' NEQ '0' (echo Requesting administrative privileges...
    set "adm=0"
    echo/ & echo "!errorlevel!" "%~nx0" "%~dp0" & echo/)
exit /b

----- Begin wsf script --->
<package>
    <job id="ADM"><script language="VBScript">
        Set UAC = CreateObject("Shell.Application") 
        WScript.Echo wscript.Arguments(0)
        UAC.ShellExecute "cmd.exe", "/c ""wscript.Arguments(0)"" ADR", "", "runas", 1 
    </script></job>
</package>  

:: Error in UAC Prompt (shown in details. Can't expand batch name correctly.)
Program location: "C:\Windows\System32\cmd.exe /c "wscript.Arguments(0)" ADR

Solution

  • Yes, it can. The trick is to submit in the cscript call all Cmd.exe arguments required to restart Cmd in Administrator mode, and read them properly in the WSF section of the batch.

    <!-- : Begin batch script
    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    CD /D "%~dp0" & echo "%*"
    set "dir=%temp%\Unzip" & set "file=%USERPROFILE%\Downloads\archive.zip"
    if not "%1"=="ADR" (call :GetAdminRights
        if defined adm cscript //nologo "%~f0?.wsf" //job:ADM "/c" "%~sf0" "ADR" )
    echo/ & >nul 2>&1 net file && (echo "!errorlevel!" Got admin rights & echo/) ^
     || (echo "!errorlevel!" No admin rights & goto :end)
    
    :: add your code here
    echo Performing admin tasks
    echo Hello >C:\tst.txt
    
    :end
    timeout /t 5 >nul
    exit /b
    
    :GetAdminRights
    REM Check for permissions
    echo/ & >nul 2>&1 net session && (echo Got admin rights) ^
     || (echo No admin rights) & echo/
    REM If error flag set, user don't have admin permissions
    if '!errorlevel!' NEQ '0' (echo Requesting admin rights...
        set "adm=0" & echo/ & echo "!errorlevel!" "%~nx0" "%~dp0" & echo/)
    exit /b
    
    ----- Begin wsf script --->
    <package>
        <job id="ADM"><script language="VBScript">
            Set UAC = CreateObject("Shell.Application") 
            args = "" 
            For Each strArg in WScript.Arguments
            args = args & strArg & " "  
            Next 
            WScript.Echo args
            UAC.ShellExecute "cmd.exe", args, "", "runas", 1 
        </script></job>
    </package>