NSIS卸载程序权限级别

时间:2017-06-13 17:41:47

标签: windows nsis uninstaller

我有一个生成卸载程序的NSIS安装程序脚本。卸载程序在创建时需要提升权限才能执行。某些要求使得我需要能够以没有提升权限级别的任何用户运行卸载程序。生成的其他所有文件都不是使用提升的权限设置的,甚至也不是应用程序可执行文件本身。有没有办法为任何用户设置权限级别?这是我的NSIS脚本。我已从脚本中删除了很多内容,以便应用程序保持匿名,但保留了我认为相关的所有内容

Function .onInit
    UserInfo::GetAccountType
    pop $0
    ${If} $0 != "admin"
        MessageBox mb_iconstop "Administrator rights required!"
        SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
        Quit
    ${EndIf}

    ${IfNot} ${AtLeastWin7}
      MessageBox MB_OK "Application requires at minimum Windows 7 as the installed operating system. Exiting installation..."
      Quit
    ${EndIf}

    IntOp $0 ${SF_SELECTED} | ${SF_RO}
    SectionSetFlags ${SecApp} $0
FunctionEnd

; sections
Section "AppSection" SecApp
    ... installer stuff
    WriteRegStr HKCU "${AppRegistryPath}" \
                     "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""

    WriteUninstaller "$INSTDIR\Uninstall.exe"
    ... more installer stuff
SectionEnd

Section "Uninstall"
    ; code that terminates the running application

    ; code that removes a firewall rule

    DetailPrint "Removing files and directories"
    Delete "$INSTDIR\*"
    Delete "$INSTDIR\x86\*"
    Delete "$INSTDIR\x64\*"
    Delete "$INSTDIR\fonts\*"
    RMDir "$INSTDIR\x86"
    RMDir "$INSTDIR\x64"
    RMDir "$INSTDIR\fonts"
    RMDir "$INSTDIR"

    DetailPrint "Removing registry values"
    DeleteRegKey HKCU "${AppRegistryPath}"
    DeleteRegKey HKCU "${AppPath}"
    DeleteRegKey HKLM "${AppRegistryPath}"
    DeleteRegKey HKLM "${AppPath}"
SectionEnd

3 个答案:

答案 0 :(得分:1)

卸载程序使用与安装程序相同的清单,清单的UAC部分由RequestExecutionLevel设置。

您可以尝试使用RequestExecutionLevel highest,它只会提升管理员,普通用户会在没有任何提示的情况下正常运行应用程序。在UserInfo::GetAccountType中使用un.onInit,如果需要提升,请中止并显示错误消息。

您也可以使用ExecShell "RunAs" '"$ExePath"'自行重新启动并请求提升(您仍需要使用UserInfo::GetAccountType验证)。

答案 1 :(得分:1)

查看UAC plugin。除此之外,它还允许您控制何时请求脚本提升,因此您可以让卸载部分跳过这样做。

答案 2 :(得分:1)

使用Windows Vista或更高版本,标记程序的正确方法是在应用程序中嵌入应用程序清单,告诉操作系统应用程序需要什么。此应用程序清单中有一些属性允许开发人员指定其程序执行级别或requested execution level

请求级别选项如下:

  • 作为Invoker - 应用程序使用与之相同的访问令牌运行 父进程。 (推荐用于标准用户应用程序)
  • 最高可用 - 应用程序以最高权限运行 当前用户可以获得。 (推荐用于混合模式应用程序)
  • 需要管理员 - 应用程序仅针对管理员运行 并要求以完全访问权限启动应用程序 管理员的令牌。 (仅限管理员使用 应用程序)
  • 无执行级别信息 - 应用程序执行此操作 没有嵌入式request execution level清单。
  

除非应用程序设计为由系统管理员专门运行,否则应该以尽可能少的权限运行。

无执行级别

在Windows Vista及更高版本上,如果在应用程序的清单中未设置任何执行级别信息,并且之前未提升应用程序,则应用程序将在传统模式中运行以获得向后兼容性支持。在此模式下,操作系统使用虚拟化机制来访问文件系统和注册表。这意味着它尝试在受限文件夹位置创建或更改文件或在注册表限制的配置单元中写入被重定向(反映)到每个用户"无障碍位置。有关此方法适用的详情,请参阅VirtualStore

有关此主题的更多信息,请访问: Windows User Account Control

在我上面链接的页面(Windows用户帐户控制)是一个链接,您可以在其中下载xml文件中包含这些request execution level属性的一些清单。在您的情况下,我可以使用您期望的执行级别编辑其中一个。使用以下代码片段可以完成此操作:

Section "Uninstall"
    !define RequestLevel User
    !define ResHacker    `${NSISDIR}\Contrib\Manifests\ResHacker.exe`
    !define ManifDir     `${NSISDIR}\Contrib\Manifests`
    !define Manifest     `NSIS_2.46_Win8`
    !packhdr             `$%TEMP%\exehead.tmp` `"${Reshacker}" -addoverwrite "%TEMP%\exehead.tmp", "%TEMP%\exehead.tmp", "${ManifDir}\${Manifest}_${RequestLevel}.manifest", 24,1,1033`

    # The rest of your code...
SectionEnd

您需要的所有必需文件都位于上述网页底部的可下载zip文件中。如何使用它也有更详细的解释。

注意:虽然我同意Anders,因为您需要提升权限来删除HKLM密钥,搞乱防火墙设置等等。