NSIS 卸载程序权限级别
Posted
技术标签:
【中文标题】NSIS 卸载程序权限级别【英文标题】:NSIS Uninstaller Permission Level 【发布时间】:2017-11-15 15:03:17 【问题描述】:我有一个生成卸载程序的 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
【问题讨论】:
【参考方案1】:卸载程序使用与安装程序相同的清单,并且清单的 UAC 部分由 RequestExecutionLevel
设置。
您可以尝试使用RequestExecutionLevel highest
,它只会提升管理员权限,普通用户会正常运行应用程序而不会出现任何提示。在un.onInit
中使用UserInfo::GetAccountType
并在需要提升时中止并显示错误消息。
您也可以通过ExecShell "RunAs" '"$ExePath"'
重新启动并请求提升(您仍需要通过UserInfo::GetAccountType
进行验证)。
【讨论】:
RequestExecutionLevel highest
不起作用。卸载程序仍然需要提升的权限。不知道你所说的第二个语句是什么意思re-launch yourself and request elevation
“RequestExecutionLevel最高”将向管理员请求提升,但这不是问题,因为 HKCU 和 $AppData 将是正确的。如果您不希望管理员默认提升权限,那么您必须使用“RequestExecutionLevel 用户”。如果您正在运行非提升并且您发现您需要提升(除非我不理解您的问题?)可以使用 RunAs 动词来完成。
...或者您的问题是您从不想要提升,但即使使用“RequestExecutionLevel 用户”,Windows 10 也会强制您提升?
我有一个需要提升权限的安装程序。在安装程序启动时,我正在检查以确保用户具有管理员权限,否则我会通知他们。我正在做很多事情,例如添加防火墙规则、添加注册表值等...但是对于卸载程序,我不希望卸载.exe 文件具有提升的权限。
这对我来说毫无意义,您需要提升卸载程序才能撤消您在安装程序中所做的事情。【参考方案2】:
查看UAC plugin。除其他外,它允许您控制何时请求脚本提升,因此您可以让卸载部分跳过此操作。
【讨论】:
因此,在我的情况下,我正在运行提升但对于一个特定区域(卸载程序),我想以非管理员身份运行。 UAC插件会这样做吗?我看到的例子是将用户提升为管理员,似乎【参考方案3】:对于 Windows Vista 或更高版本,标记程序的正确方法是在应用程序中嵌入应用程序清单,告诉操作系统应用程序需要什么。此应用程序清单中有一些属性允许开发人员指定他们的程序执行级别或requested execution level
。
请求级别选项如下:
As Invoker – 应用程序使用与 父进程。 (推荐用于标准用户应用程序) 最高可用 – 应用程序以最高权限运行 当前用户可以获得。 (推荐用于混合模式应用程序) 需要管理员 - 该应用程序只为管理员运行 并要求应用程序以完全访问权限启动 管理员的令牌。 (仅推荐给管理员 应用程序) 没有执行级别信息 – 应用程序有 没有嵌入的request execution level
清单。
除非应用程序设计为仅由系统管理员运行,否则应以尽可能低的权限运行。
无执行级别
在 Windows Vista 及更高版本上,如果未在应用程序的清单中设置执行级别信息,并且之前未提升应用程序,则应用程序以旧模式运行以获得向后兼容性支持。在这种模式下,操作系统使用虚拟化机制来访问文件系统和注册表。这意味着它在受限文件夹位置创建或更改文件或在注册表受限配置单元中写入的尝试被重定向(反映)到“每个用户”可访问的位置。请参阅VirtualStore,了解有关如何在此处应用的更多信息。
可以在此处找到有关此主题的更多信息: Windows User Account Control
在我上面链接的页面(Windows 用户帐户控制)上有一个链接,您可以在该链接中下载一些带有这些 request execution level
属性的清单在 xml 文件中。在你的情况下,我会用你想要的执行级别编辑其中一个。使用下面的 sn-p 代码可以做到这一点:
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
密钥、弄乱防火墙设置等。
【讨论】:
我认为所有这些响应都很好,但就我而言,我需要完全删除卸载程序。我正在构建一个 .NET Win32 应用程序,该应用程序也使用 Desktop Bridge Converter 将应用程序部署到 Windows 10 应用商店。为了让应用程序获得批准,它不能在提升的权限级别上运行任何东西。由于我需要能够删除注册表项等...我必须在 Win32 环境中对卸载程序具有提升的权限。但作为 Windows 10 应用程序,卸载由我负责并使用虚拟注册表。以上是关于NSIS 卸载程序权限级别的主要内容,如果未能解决你的问题,请参考以下文章