5

我有一个可以处理命令行参数和/S静默安装的安装程序。我最近升级了安装程序,通过使用UAC 插件RequestExecutionLeveladmin.user

测试表明,UAC 插件在 GUI 模式和命令行静默模式下的权限提升方面运行良好(尽管由于提升对话框,“静默”安装实际上并非完全“静默”)。

现在,客户告诉我,在将我的设置包装到第三方部署工具中时,他们的工具收到1223( ERROR_CANCELLED) 错误代码(这似乎是“用户取消了提升”)。我的设置不直接通过返回错误代码errorlevel,所以我猜测这个代码是从 UAC 插件的某个地方返回的,该插件似乎通过系统“runas”对话框周围的黑客来执行提升。

  1. 我对返回代码的来源是正确的吗?虽然当我取消提升对话框时,我得到一个错误级别 5(拒绝访问)而不是 1223

  2. 集成 UAC 插件我使用的InitElevation是开头调用的宏,.onInit可以吗?

  3. 我不确定是否正确理解 UAC 插件在静默模式下的行为:在 switch 的情况下,关键似乎在于_()插件 dll 的功能。0如果 NSIS 对话框由于静默模式不可见(或不存在?),它是否会使“runas”调用失败?在我的测试环境中,从命令行调用 silet 设置是可以的,但是如果从部署工具调用呢?

集成 UAC 插件的宏:

!macro InitElevation thing
    uac_tryagain:
    ${Debug} "Init UAC_RunElevated"
    !insertmacro UAC_RunElevated
    ;${debug} "$$0=$0 $$1=$1 $$2=$2 $$3=$3"
    ${Switch} $0
    ${Case} 0
        ${IfThen} $1 = 1 ${|} Quit ${|} ;we are the outer process, the inner process has done its work, we are done
        ${If} $3 <> 0 ;if we are admin
            System::Call "kernel32::GetCurrentProcessId()i.r0"
            ${If} ${UAC_IsInnerInstance}
                ; If we are in the elevated process, we need to get our grandparent PID for console
                ${GetProcessParent} $0 $ConsoleParentPID
                ;${Debug} "From elevated $0 process, parent process is $ConsoleParentPID"
                ${GetProcessParent} $ConsoleParentPID $ConsoleParentPID
                ;${Debug} "grand parent process is $ConsoleParentPID"
            ${Else}
                ;${Debug} "We are an already elevated process"
                StrCpy $ConsoleParentPID -1
            ${EndIf}
            ${Break}        ;we are admin (after elevation or not), let the show go on
        ${EndIf}
        ${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user
            MessageBox mb_YesNo|mb_IconExclamation|mb_TopMost|mb_SetForeground "This ${thing} requires admin privileges, try again" /SD IDNO IDYES uac_tryagain IDNO 0
        ${EndIf}
        ;fall-through and die
    ${Case} 1223
        MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "This ${thing} requires admin privileges, aborting!"
        Quit
    ${Case} 1062
        MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Logon service not running, aborting!"
        Quit
    ${Default}
        MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Unable to elevate , error $0"
        Quit
    ${EndSwitch}
    ${Debug} "End UAC_RunElevated init"
!macroend

宏调用(开头.onInit):

;abort if not started by administrator
!insertmacro InitElevation "installer"
${If} ${UAC_IsInnerInstance}
${AndIfNot} ${UAC_IsAdmin}
    SetErrorLevel 0x666666 ;special return value for outer instance so it knows we did not have admin rights
    Quit
${EndIf}
4

0 回答 0