我希望我的批处理文件只运行提升。如果没有提升,为用户提供一个选项,以提升的方式重新启动批处理。
我正在编写一个批处理文件来设置一个系统变量,将两个文件复制到Program files位置,并启动一个驱动程序安装程序。如果Windows 7/Windows Vista用户(启用了UAC,即使他们是本地管理员)在没有右键单击并选择“以管理员身份运行”的情况下运行它,他们将得到“访问拒绝”,复制这两个文件并写入系统变量。
如果用户实际上是管理员,我想使用一个命令自动重新启动提升的批处理。否则,如果他们不是管理员,我想告诉他们,他们需要管理员权限来运行批处理文件。我使用xcopy复制文件和REG ADD写入系统变量。我正在使用这些命令来处理可能的Windows XP机器。我在这个主题上发现了类似的问题,但没有一个是关于重新启动批处理文件的。
Matt给出了一个很好的答案,但它去掉了传递给脚本的任何参数。下面是我对参数的修改。我还在Windows 8中加入了Stephen对工作目录问题的修复。
@ECHO OFF
setlocal EnableDelayedExpansion
::net file to test privileges, 1>NUL redirects output, 2>NUL redirects errors
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto START ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' ( goto START )
set "batchPath=%~f0"
set "batchArgs=ELEV"
::Add quotes to the batch path, if needed
set "script=%0"
set script=%script:"=%
IF '%0'=='!script!' ( GOTO PathQuotesDone )
set "batchPath=""%batchPath%"""
:PathQuotesDone
::Add quotes to the arguments, if needed.
:ArgLoop
IF '%1'=='' ( GOTO EndArgLoop ) else ( GOTO AddArg )
:AddArg
set "arg=%1"
set arg=%arg:"=%
IF '%1'=='!arg!' ( GOTO NoQuotes )
set "batchArgs=%batchArgs% "%1""
GOTO QuotesDone
:NoQuotes
set "batchArgs=%batchArgs% %1"
:QuotesDone
shift
GOTO ArgLoop
:EndArgLoop
::Create and run the vb script to elevate the batch file
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs"
ECHO UAC.ShellExecute "cmd", "/c ""!batchPath! !batchArgs!""", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs"
"%temp%\OEgetPrivileges.vbs"
exit /B
:START
::Remove the elevation tag and set the correct working directory
IF '%1'=='ELEV' ( shift /1 )
cd /d %~dp0
::Do your adminy thing here...
我使用了Matt的精彩答案,但我发现在运行提升脚本时,Windows 7和Windows 8系统之间存在差异。
在Windows 8上提升脚本后,当前目录将被设置为c:\Windows\system32。幸运的是,有一个简单的解决方法,将当前目录更改为当前脚本的路径:
cd /d %~dp0
注意:使用cd /d确保驱动器号也被更改。
要测试这一点,可以将以下内容复制到脚本中。在两个版本上正常运行可以看到相同的结果。以Admin身份运行,看看Windows 8的区别:
@echo off
echo Current path is %cd%
echo Changing directory to the path of the current script
cd %~dp0
echo Current path is %cd%
pause