@echo off & setlocal
:: Check if the current session is already elevated.
:: `net session` only succeeds in elevated sessions.
net session >NUL 2>&1 && goto :ELEVATED
:: Getting here means that we must reinvoke with elevation.
:: Add -Wait before -Verb RunAs to wait for the reinvocation to exit.
set ELEVATE_CMDLINE=cd /d "%~dp0" ^& "%~f0" %*
powershell.exe -noprofile -c Start-Process -Verb RunAs cmd.exe \"/k $env:ELEVATE_CMDLINE\"
exit /b %ERRORLEVEL%
:: Getting here means that we are (now) running with elevation.
:ELEVATED
echo === Running in elevated session:
echo Script file : %~f0
echo Arguments : %*
echo Working dir : %cd%
说到 Amr Ali 的 WSH 辅助答案; 这里有一个重新表述,使得通过参数的传递更加健壮,这样参数如 "a & b"可以被传递,并通过避免使用 call-see line set ELEVATE_CMDLINE=...来防止在参数中重复 "^"字符; 此外,除了一些可读性格式外,它还确保了没有任何原始的批处理语句被意外回显:
<!-- : (":" is required)
@echo off & setlocal
net session >NUL 2>&1 && goto :ELEVATED
set ELEVATE_CMDLINE=cd /d "%~dp0" ^& "%~f0" %*
cscript.exe //nologo "%~f0?.wsf" //job:Elevate & exit /b
-->
<job id="Elevate">
<script language="VBScript">
Set objShell = CreateObject("Shell.Application")
Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objWshProcessEnv = objWshShell.Environment("PROCESS")
strCommandLine = Trim(objWshProcessEnv("ELEVATE_CMDLINE"))
objShell.ShellExecute "cmd", "/k " & strCommandLine, "", "runas"
</script>
</job>
:ELEVATED
echo === Running in elevated session:
echo Script file: %~f0
echo Arguments : %*
echo Working dir: %cd%