使用Win7和UAC插件进行无提示安装

时间:2013-01-03 15:18:24

标签: nsis uac silent-installer

我有一个可以处理命令行参数和/S静默安装的安装程序。我最近升级了安装程序,以便更好地符合Vista / W7 UAC管理标准,方法是使用UAC plugin并将RequestExecutionLeveladmin切换为user

测试显示UAC插件在GUI模式和命令行静默模式下正常工作(虽然“静音”安装实际上并非完全“静音”,因为提升对话框)。

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

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

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

  3. 我不确定UAC插件在静默模式下的行为是否正确:密钥似乎在插件dll的_()函数中,在0的情况下开关。如果NSIS dilaog由于静默模式不可见(或不存在?),是否会使“runas”调用失败?在我的测试环境中,从命令行调用silet设置时没关系,但是如果从部署工具调用了什么呢?

  4. 集成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}
    

0 个答案:

没有答案