【问题标题】:NSIS installer .onInit and un.onInit run twice because of UACNSIS 安装程序 .onInit 和 un.onInit 由于 UAC 运行两次
【发布时间】:2016-08-29 15:43:20
【问题描述】:

您好,我正在重构一个旧的安装脚本并遇到了 UAC 插件创建的问题。由于!insertmacro Init "installer".onInit 运行了两次。 !insertmacro Init "uninstaller"un.onInit 函数也是如此。

因此,安装程序和卸载程序运行两次,这不是我想要的行为。 I have read that the UAC creates an inner process with elevated permissions,这是必需的,因为它涉及 C:/ 驱动器,但外部进程也运行安装程序。

由于安装脚本很长,我只粘贴了.onInit 函数。整个.nsi 脚本可以在here 找到。

!insertmacro 注释掉该行可确保.onInit 函数运行一次,但不再运行安装程序。那么如何让安装程序和卸载程序只运行一次,并具有正确的(管理员)权限?

感谢任何建议或回答:)

Function .onInit
MessageBox MB_OK "In .onInit"
  SetShellVarContext all

  !insertmacro Init "installer"

  System::Call 'kernel32::CreateMutexA(i 0, i 0, t "Tribler") i .r1 ?e'

  Pop $R0
  StrCmp $R0 0 checkinst

  MessageBox MB_OK "The installer is already running."
  Abort

  checkinst:
  ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}" "UninstallString"
  StrCmp $R0 "" done
  IfFileExists $R0 showuninstdialog done

  showuninstdialog:
  MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "${PRODUCT} is already installed. $\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade." /SD IDCANCEL IDOK uninst
  Abort

  uninst:
    ClearErrors
    ; Laurens (2016-03-29): Retrieve the uninstallString stored in the register. Do NOT use $INSTDIR as this points to the current $INSTDIR var of the INSTALLER, 
    ; which is the default location at this point.
    ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}" "UninstallString"
 MessageBox MB_OK "$R0"
    ExecWait '"$R0"' ;Do not copy the uninstaller to a temp file
    ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}" "UninstallString"
    StrCmp $R0 "" done
    Abort
  done:

FunctionEnd

【问题讨论】:

  • 您在此处粘贴的 .onInit 代码与您链接的代码不匹配!您链接到的代码有一个明显的问题,如果不测试自己,无法真正判断粘贴在这里的代码是否有问题,但在您澄清我应该测试的代码之前,我不会这样做。有一些关于使用的 NSIS/UAC 插件/Windows 版本的信息也很好......
  • @Anders 我在键入此内容时正在推动和尝试几件事。抱歉,如果现在有所不同。将链接中的代码视为我正在运行的当前代码。另外,我正在 Windows 2008 64 位服务器上构建它,并在 Windows 10 机器上测试安装过程,也是 64 位。
  • @Anders 我已经撤消了一些实验性更改并推送了它们。我暂时不会推动它,因为当人们看到它时确实会让人感到困惑。

标签: installation nsis uninstallation


【解决方案1】:

您链接到的代码(至少在我查看时)在 .onInit 中同时调用了 !insertmacro UAC_RunElevated!insertmacro Init "installer",因此难怪它运行了多次。在调用!insertmacro UAC_RunElevated 后,您必须始终检查$0,因为您可能必须根据其值调用Quit

我假设 Init 宏是我编写的(?)所以它应该可以正常工作;)

我个人建议您牺牲完成页面上的运行复选框,然后您可能根本不必使用 UAC 插件...

【讨论】:

  • 感谢您的回答安德斯,我已插入 UAC_RunElevated 作为测试,看看我做的第一件事是否是获得额外的权限,也许我可以添加一个检查,看看是否有任何参数我可以检查@idleberg 提到的。不幸的是,那里只有 !insertmacro Init “安装程序”也会让它运行两次。
  • 我将检查是否可以按照您的建议在不使用 UAC 插件的情况下执行此操作,到目前为止感谢您的帮助和建议 :)
  • 我删除了它,在这里和那里重构了文件,它运行得非常好。谢谢!
【解决方案2】:

据我所知,UAC 插件使用特殊参数重新启动安装程序。您可以使用GetParametersGetOptions.onInit 中检查,然后有条件地显示一条消息:

# get all commandline parameters
${GetParameters} $0

# parse specific option
${GetOptions} $0 "/UAC:" $1

# do stuff
IfErrors 0 +2
MessageBox MB_OK "No admint" IDOK +2
MessageBox MB_OK "Admin"

就个人而言,我会在最后一部分使用LogicLib

# do stuff
${If} $1 == ""
  MessageBox MB_OK "Not admin"
${Else}
 MessageBox MB_OK "Admin"
${Endif}

【讨论】:

  • 感谢您的建议。我已经添加了您建议的行,它在第一次运行时显示一个空对话框,在提升权限对话框后的第二次运行时显示/UAC:<number> /NCRC。所以听起来我想要后一种情况,有没有办法检查这个?
猜你喜欢
  • 2016-06-30
  • 2012-05-21
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多