如果拒绝UAC提示,则正常运行批处理文件

时间:2014-10-12 06:38:51

标签: batch-file uac

我想创建一个批处理文件,提示管理员权限,但不仅仅是这样(在发布之前读到结束)。通常我会通过批处理文件创建一个vbs脚本,它会提示管理员权限,但问题是如果用户在UAC窗口中选择“否”,批处理文件将无法运行,我希望它仍然可以运行(与或没有管理员权限)。我的代码(错误/不完整):

@echo off

if "%1" == "S" goto skip

::checks if the user already have admin rights, in this case no prompt needed
net file 1>nul 2>nul
if '%errorlevel%' == '0' goto skip

::create vbs script from which the batch file should run
echo Set UAC = CreateObject^("Shell.Application"^) > runasAdmin.vbs
echo UAC.ShellExecute "%~0", "S", "", "runas", 1 >> runasAdmin.vbs
start "" runasAdmin.vbs
::here, a code should check if the batch file is running as admin in another process
::if not, goto skip
exit /b

:skip

::commands and stuff...

2 个答案:

答案 0 :(得分:1)

检查进程是否以管理员身份运行的问题是非管理员无法看到管理进程。即保护管理过程免受非抬高的眼睛的影响。所以,那是行不通的。

ShellExecute在您编写代码时返回一个HWnd,此值可用于检查错误,但当然这也不适用于shell.application com对象。因此,您无法检查返回并为要检查的球棒执行一个不错的WScript.Quit(错误值)。

使用start "" runasAdmin.vbs表示您的bat文件直接进入下一行,而不是等到UAC提示完成。使用start /wait甚至更简单的cscript -nologo可确保蝙蝠等待,直到提示被回答。

因此,您无法通过VBS检查提升流程创建的成功/失败,也无法检查流程。我能想到的就是使用临时文件创建作为锁定机制。为了使这项工作,提升的进程需要创建一个非提升进程检查的临时文件,因此需要在每个进程中进行小睡眠(使用localhost ping实现)。

@echo off
setlocal

rem Note: Any user entered parameter will run unelevated
set runningFile=%1
if not defined runningFile goto checkElevation
echo Running as admin > %runningFile%
goto skip

:checkElevation
rem checks if the user already have admin rights, in this case no prompt needed
net file 1>nul 2>nul
if '%errorlevel%' == '0' goto skip

rem create vbs script from which the batch file should run
set filename=%tmp%\RunAsAdmin%random%
set runningFile="%filename%.lck"
set vbscript="%filename%.vbs"
echo Set UAC = CreateObject^("Shell.Application"^) > %vbscript%
echo UAC.ShellExecute "%0", %runningFile%, "", "runas", 1 >> %vbscript%
cscript -nologo %vbscript%
rem sleep 1 to allow elevated version to create lock file
ping -n 2 127.0.0.1 > NUL
del %vbscript%
rem check if running file has been created
if not exist %runningFile% goto skip
if exist %runningFile% del /f %runningFile%
exit /b

:skip
rem sleep 1 so that non elevated version can check lock file created
ping -n 2 127.0.0.1 > NUL
echo Running other things here %1

if exist %runningFile% del /f %runningFile%
pause
rem commands and stuff...

答案 1 :(得分:-1)

我优化了以下代码:

@echo off
@title 
@NET FILE 1>nul 2>nul
@if %ERRORLEVEL% neq 0 (
    @if not defined UAC (
        @set UAC=1;
    ) else (
        @echo. 
        @echo UAC elevating failed !
        @echo.
        @pause
        @exit
    )
    @echo CreateObject^("Shell.Application"^).ShellExecute "%~f0", "%*", "%~dp0", "runas", 1 > %temp%\UACtemp.vbs
    @%temp%\UACtemp.vbs
    @del /f /q %temp%\UACtemp.vbs
    @exit
)
@cd /d %~dp0
@echo on
::command under this line