我希望我的批处理文件只运行提升。如果没有提升,为用户提供一个选项,以提升的方式重新启动批处理。
我正在编写一个批处理文件来设置一个系统变量,将两个文件复制到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...
我是这样做的:
NET SESSION
IF %ERRORLEVEL% NEQ 0 GOTO ELEVATE
GOTO ADMINTASKS
:ELEVATE
CD /d %~dp0
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 1);close();"
EXIT
:ADMINTASKS
(Do whatever you need to do here)
EXIT
这样做很简单,只使用windows默认命令。
如果你需要重新分发你的批处理文件,这是很好的。
CD /d %~dp0将当前目录设置为文件的当前目录(如果还不是,则与文件所在的驱动器无关,这要归功于/d选项)。
返回当前带扩展名的文件名(如果你不包含扩展名,并且文件夹中有一个同名的exe,它将调用exe)。
这个帖子有这么多回复,我甚至不知道我的回复是否会被看到。
无论如何,我发现这种方法比其他答案上提出的其他解决方案更简单,我希望它能帮助到一些人。