Inno setup 仅在需要时使Inno安装程序请求权限提升

Inno setup 仅在需要时使Inno安装程序请求权限提升,inno-setup,uac,privileges,pascalscript,elevated-privileges,Inno Setup,Uac,Privileges,Pascalscript,Elevated Privileges,如果需要提升权限,安装程序具有可用于控制安装程序启动时的权限。我希望我的安装程序即使对非管理员用户也能工作(将我的应用程序安装到用户文件夹,而不是程序文件),这没有问题。因此,我将PrivilegesRequired设置为none(未记录的值)。这使得UAC提示仅针对管理员用户弹出,因此他们甚至可以安装到程序文件中。对于非管理员用户没有UAC提示,因此即使他们也可以安装应用程序(到用户文件夹) 但这也有一些缺点: 有些人在他们的机器上使用不同的管理员和非管理员帐户,通常使用非管理员帐户。通常,

如果需要提升权限,安装程序具有可用于控制安装程序启动时的权限。我希望我的安装程序即使对非管理员用户也能工作(将我的应用程序安装到用户文件夹,而不是
程序文件
),这没有问题。因此,我将
PrivilegesRequired
设置为
none
(未记录的值)。这使得UAC提示仅针对管理员用户弹出,因此他们甚至可以安装到
程序文件中。对于非管理员用户没有UAC提示,因此即使他们也可以安装应用程序(到用户文件夹)

但这也有一些缺点:

  • 有些人在他们的机器上使用不同的管理员和非管理员帐户,通常使用非管理员帐户。通常,当使用非管理员帐户启动安装时,当他们收到UAC提示时,他们输入管理员帐户的凭据以继续。但这对我的安装程序不起作用,因为没有UAC提示
  • (过于可疑)具有管理员帐户的人,如果想要安装到用户文件夹,在没有(不需要)管理员权限的情况下无法启动我的安装程序
是否有办法仅在需要时(当用户选择仅可由管理员帐户写入的安装文件夹时)使Inno安装请求权限提升

我想在Inno设置中没有这个设置。但可能有一种编程解决方案(Inno Setup Pascal脚本)或某种插件/DLL



请注意,Inno Setup 6内置了对的支持。

在Inno Setup的生命周期内,没有内置的方式来有条件地提升安装过程。但是,您可以使用
runas
动词执行设置过程,并杀死非提升的谓词。我写的脚本有点棘手,但展示了一种可能的方法

警告:

这里使用的代码总是试图执行提升的安装实例;没有检查是否实际需要标高(如何确定是否需要标高,请另问一个问题)。而且,我现在也说不出这样做是否安全。我不确定Inno安装程序是否(或不会)以某种方式依赖于
PrivilegesRequired
指令的值。最后,这个提升功能应该只在相关的Windows版本上执行。此脚本中未对此进行任何检查:

[设置]
AppName=我的程序
AppVersion=1.5
DefaultDirName={pf}\My程序
所需特权=最低
[守则]
#ifdef UNICODE
#定义AW“W”
#否则
#定义“A”
#恩迪夫
类型
HINSTANCE=THandle;
程序ExitProcess(UEXIT代码:UINT);
外部的ExitProcess@kernel32.dllstdcall';
函数ShellExecute(hwnd:hwnd;lpOperation:string;lpFile:string;
lpParameters:string;lpDirectory:string;nShowCmd:Integer):HINSTANCE;
外部“ShellExecute{#AW}@shell32.dll stdcall”;
变量
提升:布尔值;
pagesskiped:布尔值;
函数CmdLineParamExists(常量值:字符串):布尔值;
变量
I:整数;
开始
结果:=假;
对于I:=1的参数
如果CompareText(ParamStr(I),Value)=0,则
开始
结果:=真;
出口
结束;
结束;
程序初始化;
开始
{初始化我们的助手变量}
提升:=CmdLineParamExists('/ELEVATE');
PagesSkiped:=False;
结束;
函数ShouldSkipPage(PageID:Integer):布尔值;
开始
{如果我们已将此实例作为提升实例执行,则跳过页面,除非我们}
{在目录选择页上}
结果:=未分页跳过并提升和(PageID wpSelectDir);
{如果已到达目录选择页面,请设置标志变量}
如果没有结果的话
PagesSkiped:=真;
结束;
函数NextButtonClick(CurPageID:Integer):布尔值;
变量
参数:字符串;
RetVal:HINSTANCE;
开始
结果:=真;
{如果我们在目录选择页上并且没有运行}
{我们手动提升的实例,然后…}
如果未提升且(CurPageID=wpSelectDir),则
开始
{将已选择的目录传递给执行参数并}
{包括我们自己的自定义/提升参数,用于告诉}
{设置为跳过所有页面并进入目录选择页面}
参数:=ExpandConstant('/DIR=“{app}”/ELEVATE');
{因为无法使用ShellExec执行安装加载程序}
{函数,我们需要使用WinAPI解决方法}
RetVal:=ShellExecute(WizardForm.Handle,'runas',
ExpandConstant({srceexe}'),Params',SW_SHOW);
{如果此安装程序的提升执行成功,则…}
如果RetVal>32,则
开始
{退出此非提升的安装实例}
退出过程(0);
结束
其他的
{由于某种原因,执行此安装程序失败;可能有一个常见原因}
{只需关闭UAC对话框}
开始
{此情况由您自行处理,此行强制向导}
{停留在当前页面上}
结果:=假;
{并可能向用户显示一些错误消息}
MsgBox(格式('提升此安装程序失败。代码:%d',[RetVal]),
b错误,b_正常);
结束;
结束;
结束;

Inno Setup 6内置了对的支持

基本上,您可以简单地设置:


以下是我的(现已过时)Inno Setup 5解决方案,基于

当设置以非提升方式启动时,它将请求提升,但有一些例外情况:

  • 仅适用于Windows Vista和更新版本(尽管它也适用于Windows XP)
  • 升级时,安装程序将检查当前用户是否具有对以前安装位置的写入权限。如果用户具有写入权限,安装程序将不会请求提升。因此,如果用户以前已将应用程序安装到用户文件夹,则升级时不会请求提升
如果用户拒绝新安装的提升,安装程序将
[Setup]
PrivilegesRequiredOverridesAllowed=commandline dialog