[英]NSIS installer .onInit and un.onInit run twice because of UAC
Hello I am refactoring an old install script and run into the issue that the UAC plugin creates. 您好,我正在重构旧的安装脚本,并遇到UAC插件创建的问题。 Because of the !insertmacro Init "installer"
the .onInit
runs twice. 由于!insertmacro Init "installer"
, .onInit
运行两次。 The same goes for !insertmacro Init "uninstaller"
and the un.onInit
function. !insertmacro Init "uninstaller"
和un.onInit
函数也是un.onInit
。
Because of this, the installer and the uninstaller run twice which is not the behavior I want. 因此,安装程序和卸载程序运行两次,这不是我想要的行为。 I have read that the UAC creates an inner process with elevated permissions , which IS required as it touches the C:/
drive for example, but the outer process also runs the installer. 我已经读到UAC创建了一个内部进程 ,该进程具有提升的权限 ,例如,它在接触C:/
驱动器时是必需的,但是外部进程也运行安装程序。
Because the install script is quite long I only paste the .onInit
function. 因为安装脚本很长,所以我只粘贴.onInit
函数。 The whole .nsi
script can be found here . 整个.nsi
脚本可在此处找到。
Commenting out the line with the !insertmacro
makes sure the .onInit
function runs once, but does not run the installer anymore. 用!insertmacro
注释掉该行可确保.onInit
函数运行一次,但不再运行安装程序。 So how can I make the installer and the uninstaller only run once, with the right (admin) permissions? 那么,如何使安装程序和卸载程序仅具有正确的(admin)权限运行一次?
I appreciate any suggestion or answer :) 我感谢任何建议或答案:)
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
The code you linked to (at least when I looked at it) called both !insertmacro UAC_RunElevated
and !insertmacro Init "installer"
in .onInit so no wonder it ran multiple times. 您链接的代码(至少在我看来是这样)在!insertmacro UAC_RunElevated
都称为!insertmacro UAC_RunElevated
和!insertmacro Init "installer"
,因此难怪它多次运行。 After calling !insertmacro UAC_RunElevated
you must always check $0
because you might have to call Quit
depending on its value! 调用!insertmacro UAC_RunElevated
您必须始终检查$0
因为您可能必须根据其值调用Quit
!
I assume that Init macro is something I wrote(?) so it should work correctly ;) 我假设Init宏是我写的东西(?),所以它应该可以正常工作;)
I would personally recommend that you sacrifice the run checkbox on the finish page and then you probably don't have to use the UAC plug-in at all... 我个人建议您在完成页面上放弃运行复选框,然后可能根本不必使用UAC插件...
As far as I remember, the UAC plugin restarts the installer with a special parameter. 据我所知,UAC插件使用特殊参数重启安装程序。 You can check for that in your .onInit
using GetParameters
and GetOptions
, then show a message conditionally: 您可以使用GetParameters
和GetOptions
在.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"
Personally, I'd use LogicLib
for the last part: 就个人而言,我将在最后一部分中使用LogicLib
:
# do stuff
${If} $1 == ""
MessageBox MB_OK "Not admin"
${Else}
MessageBox MB_OK "Admin"
${Endif}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.