您如何使用 NSIS 请求管理员权限?

Posted

技术标签:

【中文标题】您如何使用 NSIS 请求管理员权限?【英文标题】:How do you request administrator permissions using NSIS? 【发布时间】:2012-02-02 15:48:25 【问题描述】:

我对 NSIS 很陌生。 我正在尝试请求管理员权限以运行安装程序,因为它与注册表有点混乱。 我对“RequestExecutionLevel”和“MULTIUSER_EXECUTIONLEVEL”的问题是它们都绝对阻止任何非管理员用户打开安装程序,即使在上下文菜单中选择“以管理员身份运行”也是如此。 我曾尝试使用 RunAs DLL,但我还没有找到一个线程来说明将什么放入传递给“RunAsW”函数的 $command 变量中。

这是我的(相当修改的)代码:

     StrCpy $0 0
     StrCpy $1 ""
     System::Call 'RunAs::GetAdministrators(w r1, *i .r0) i .r2 ? u'
     System::Alloc 64
     Pop $4
     StrCpy $4 $2
     StrCpy $5 ""
     loop:
          IntCmp $0 0 endloop
          System::Call '*$4(w .r3)'
          StrCpy $5 "$5|$3"
    endloop:
    System::Free $4   ; we free the memory used by the array
    StrCpy $5 "$5" "" 1
    !insertmacro MUI_INSTALLOPTIONS_WRITE "Settings.ini" "Field 1" "ListItems" $5
     !insertmacro MUI_INSTALLOPTIONS_DISPLAY "Settings.ini"
     !insertmacro MUI_INSTALLOPTIONS_READ $1 "UserPass" "Field 1" "State"
     !insertmacro MUI_INSTALLOPTIONS_READ $2 "Settings.ini" "Field 2" "State"
     StrCpy $3 "%%LOGONSERVER%%"
     StrCpy $3 0
     StrCpy $4 0
     System::Call 'RunAs::RunAsW(w r1, w r2, w r3, *w .r4) i .r0 ? u'
     MessageBox MB_OK $0
     IntCmp $0 1 success
     Quit
     success:
     !insertmacro MUI_LANGDLL_DISPLAY

其中很多只是猜测和反复试验。 (顺便说一句 - 我也尝试通过循环运行以获取所有管理员,但似乎 DLL 仅适用于 32 位机器,所以......)。

无论如何,我的问题是:

是否有人知道一种方法(使用“RunAs”或其他方式)打开一个请求用户名和密码的对话框,检查凭据并仅在他们签出后继续安装?

另外,我知道有一种方法可以设置安装程序,以便它带有漂亮的盾牌图标,让用户知道将请求管理员权限。有人知道怎么做吗?

非常感谢任何帮助,因为这是目前阻止我的应用部署的唯一原因。

【问题讨论】:

“System::Alloc 64”有什么意义,你在弹出后扔掉指针并泄漏内存。 NSIS 始终是 32 位的,因此您对循环的评论毫无意义...... “他们都绝对阻止任何非管理员用户打开安装程序,即使在上下文菜单中选择“以管理员身份运行”也是如此”这听起来不对!您的 Windows 版本和 UAC 设置是什么? $command 变量是你要执行的东西,“calc.exe”等 【参考方案1】:
Outfile RequireAdmin.exe
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)

!include LogicLib.nsh

Function .onInit
UserInfo::GetAccountType
pop $0
$If $0 != "admin" ;Require admin rights on NT4+
    MessageBox mb_iconstop "Administrator rights required!"
    SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
    Quit
$EndIf
FunctionEnd

Page InstFiles

Section
SectionEnd

是我通常推荐用来确保安装程序以管理员身份运行的基本代码。

恕我直言,在自定义页面上提示输入凭据是没有意义的,除非只有部分安装过程需要管理员访问权限,而另一部分需要访问用户配置文件。如果这适用于您,那么您应该查看UAC plug-in(使用起来有点复杂,并且您的 exe 文件无法获取屏蔽覆盖图标)

我认为 RunAs plug-in 在 UAC 开启时无法在 Vista+ 上正常工作,因此试图让它工作可能是死路一条...

获取屏蔽的recommended way 是在exe 清单中请求提升,RequestExecutionLevel admin 就是这样做的。如果您在脚本中根本不使用RequestExecutionLevel,您的安装程序可能会被检测为旧版安装程序,并且还会获得屏蔽覆盖。

在 Windows Vista 中,如果可执行文件需要提升才能启动, 那么可执行文件的图标应该用盾牌图标“标记”以 表明这一事实。可执行文件的应用程序清单必须标记 “requireAdministrator”将可执行文件指定为需要完整的 管理访问令牌。盾牌图标覆盖也将是 自动放置在被认为需要的可执行文件上 根据安装程序检测启发式提升。例如,一个 名为 setup.exe 的文件将自动收到一个盾牌图标覆盖 即使可执行文件没有嵌入式应用程序清单。

【讨论】:

谢谢安德斯。恢复为仅 RequestExecutionLevel w/o RunAs 并通过将“RequestExecutionLevel admin”移动到页面顶部来解决它。现在 Windows 会自动提示管理员登录...

以上是关于您如何使用 NSIS 请求管理员权限?的主要内容,如果未能解决你的问题,请参考以下文章

NSIS小记:管理员权限和开机自动启动

根据安装程序的 NSIS 卸载程序权限

管理员级别的 nsis 安装程序需要为非特权用户创建图标

在运行时请求管理员权限

在运行时请求管理员权限

如何将 NSIS 的 RequestExecutionLevel 选项添加到 CMakeLists.txt