我希望我的批处理文件只运行提升。如果没有提升,为用户提供一个选项,以提升的方式重新启动批处理。
我正在编写一个批处理文件来设置一个系统变量,将两个文件复制到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...
如果不是,我使用PowerShell重新启动提升的脚本。把这些句子放在你剧本的最上面。
net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c %~fnx0 %*'"
goto :eof
:run
:: TODO: Put code here that needs elevation
我从@Matt的答案中复制了“net name”方法。他的回答有更好的文档记录,并有错误消息等。这个版本的优势在于PowerShell已经在Windows 7及以上版本上安装并可用。没有临时VBScript (*.vbs)文件,也不需要下载工具。
只要您的PowerShell执行权限没有被锁定,这个方法应该不需要任何配置或设置就可以工作。
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...