AMock
14th September 2010 14:19 UTC
NSIS Array: Problem when using user function in installer AND uninstaller
Hi,
I used NSISArray in some functions in an installer (install sections).
Now when I encapsulate the functions as macros to be able to use them in the
uninstaller too, I get
!error: NSISArray: An array can only be initialised once.
Is there an elegant way to use the same user defined function using NSISArray both in installer and uninstaller parts. NSIS requests that uninstaller functions must be preceded by "un."
Code:
!include NSISArray.nsh
>${Array} "Devices" 40 5
>${ArrayFunc} Inited
>${ArrayFunc} Shift
>${ArrayFunc} SizeOf
>${ArrayFunc} ReadFirst
>${ArrayFunc} ReadNext
>${ArrayFunc} ReadClose
>!ifdef USE_DEBUGGER
>${ArrayFunc} Debug
>!endif
!macro Init_Devices un
>Function ${un}Init_Devices
${Devices->Init}
>FunctionEnd
>!macroend
>!macro Done_Devices un
>Function ${un}Done_Devices
${Devices->Inited} 0 empty1
${Devices->Delete}
empty1:
>FunctionEnd
>!macroend
>:
;+other functions working on array Devices, declared as macros the same way
>:
:
; Installer section
>!insertmacro Init_Devices ""
>; Uninstaller section
>!insertmacro Init_Devices "un."
Afrow UK
14th September 2010 14:25 UTC
You just need to define another array for use in the uninstaller.
Stu
AMock
14th September 2010 14:46 UTC
First I thought that I'd have to throw a lot of !ifdef...!endif into my functions....
But then I just put
nsh
>${Array} "Devices" 40 5
>${ArrayFunc} Inited
>${ArrayFunc} Shift
>${ArrayFunc} SizeOf
>${ArrayFunc} ReadFirst
>${ArrayFunc} ReadNext
>${ArrayFunc} ReadClose
>!ifdef USE_DEBUGGER
>${ArrayFunc} Debug
>!endif
${Array}"un.Devices" 40 5
>${ArrayFunc} Inited
>${ArrayFunc} Shift
>${ArrayFunc} SizeOf
>${ArrayFunc} ReadFirst
>${ArrayFunc} ReadNext
>${ArrayFunc} ReadClose
>!ifdef USE_DEBUGGER
>${ArrayFunc} Debug
>!endif
!macro Init_Devices un
>Function ${un}Init_Devices
${${un}Devices->Init}
>FunctionEnd
>!macroend
>!macro Done_Devices un
>Function ${un}Done_Devices
${${un}Devices->Inited} 0 empty1
${${un}Devices->Delete}
empty1:
>FunctionEnd
>!macroend
>
and using ${un} in the worker functions accordingly:
e.g.
Call ${un}Init_Devices
Push 'PCI'
Call ${un}GetDeviceList
${${un}Devices->SizeOf} $R0 $R1 $R2
${${un}Devices->ReadFirst} $R0 $R1
${${un}Devices->ReadNext} $R0 $R1
${${un}Devices->ReadClose} $R0
Call ${un}Done_Devices
looks a little strange/cryptic, but the NSIS compiler no longer complains.
Thanks for the idea!