由于 UAC,NSIS 安装程序 .onInit 和 un.onInit 运行 两次

NSIS installer .onInit and un.onInit run twice because of UAC

你好,我正在重构一个旧的安装脚本和 运行 到 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

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

# get all commandline parameters
${GetParameters} [=10=]

# parse specific option
${GetOptions} [=10=] "/UAC:" 

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

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

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

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

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

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