Windows NSIS卸载程序权限级别

Windows NSIS卸载程序权限级别,windows,nsis,uninstallation,Windows,Nsis,Uninstallation,我有一个生成卸载程序的NSIS安装程序脚本。卸载程序在创建时需要提升权限才能执行。某些要求使得我需要能够在没有提升权限级别的情况下以任何用户的身份运行卸载程序。生成的其他文件都没有设置提升权限,甚至应用程序可执行文件本身也没有。有没有办法为任何用户设置权限级别?这是我的NSIS脚本。我从脚本中删除了很多内容,以便应用程序保持匿名,但保留了我认为相关的所有内容 Function .onInit UserInfo::GetAccountType pop $0 ${If} $0

我有一个生成卸载程序的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

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


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


您还可以重新启动自己,并使用
ExecShell“RunAs”“$ExePath”
请求提升(您仍然需要使用
UserInfo::GetAccountType
进行验证)。除其他外,它允许您控制何时请求脚本提升,因此您可以让卸载部分跳过此操作。

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

请求级别选项如下所示:

  • 作为调用方–应用程序使用与调用方相同的访问令牌运行 父进程。(推荐用于标准用户应用程序)
  • 最高可用权限–应用程序以用户的最高权限运行 当前用户可以获得。(建议用于混合模式应用)
  • 需要管理员–应用程序仅为管理员运行 并要求应用程序以完全访问权限启动 管理员的令牌。(仅建议管理员使用) 应用程序)
  • 没有执行级别信息–应用程序没有 没有嵌入的
    请求执行级别
    清单
除非应用程序设计为仅由系统管理员运行,否则它应该以尽可能少的权限运行

没有执行级别 在Windows Vista及更高版本上,如果应用程序的清单中未设置执行级别信息,并且应用程序以前未提升,则应用程序将以旧模式运行,以支持向后兼容。在此模式下,操作系统使用虚拟化机制让文件系统和注册表进行访问。这意味着,它尝试在受限文件夹位置创建或更改文件,或在注册表受限配置单元中写入文件时,会重定向(反映)到“每个用户”可访问的位置。有关如何在此处应用的更多信息,请参阅

有关此主题的更多信息可在此处找到:


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

“卸载”部分 !定义请求级用户 !定义ResHacker`${NSISDIR}\Contrib\Manifests\ResHacker.exe` !定义ManifDir`${NSISDIR}\Contrib\ManifDir清单` !定义清单'NSIS_2.46_Win8` !packhdr`$%TEMP%\exehead.tmp``${Reshacker}“-addoverwrite”%TEMP%\exehead.tmp“,%TEMP%\exehead.tmp“,“${ManifDir}\${ManifDir}{Manifest}{RequestLevel}.Manifest”,24,11033` #剩下的代码。。。 分段结束
您需要的所有文件都位于上述网页底部的可下载zip文件中。如何使用它也被更详细地解释


注意:尽管我同意Anders的观点,因为您需要更高的权限来删除
HKLM
密钥、干扰防火墙设置等。

RequestExecutionLevel highest
不起作用。卸载程序仍然需要提升的权限。不确定您所说的第二条语句“re launch yourself and request elevation”
“RequestExecutionLevel highest”将向管理员请求提升,但这不是问题,因为HKCU和$AppData是正确的。如果您也不希望管理员在默认情况下提升,则必须使用“RequestExecutionLevel用户”。如果您运行的是非提升版,并且您发现您需要提升(除非我不理解您的问题?)可以使用RunAs动词来完成……或者您的问题是您永远不想要提升,但Windows 10强制您使用“RequestExecutionLevel user”来提升?我有一个需要提升权限的安装程序。在安装程序启动时,我正在检查用户是否具有管理员权限,否则,我会通知他们。我正在做很多事情,比如添加防火墙规则,添加注册表值等等。。。但对于卸载程序,我不希望uninstall.exe文件具有提升权限。这对我来说毫无意义,您需要提升卸载程序以撤消您在安装程序中所做的操作。因此,在我的情况下,我运行提升,但对于一个特定区域(卸载程序),我希望以非管理员身份运行。UAC插件能做到这一点吗?我看到的例子是将用户提升为管理员,看起来我认为所有这些响应都很好,但在我的情况下,我需要删除unin