Archive: macro within a macro


macro within a macro
I've seen (and am using) the code to define a single function and use it for both installer and uninstaller.

I've run into a problem where I'm using a third-party macro within my function and the builder is complaining that I need to have "un." before uninstall functions and not in front of install functions. How do I get around this without writing two functions?


!macro myfunc un
Function ${un}myfunc
Call ${un}someotherfunc ; this works
${ThirdPartyMacro} $arg1 $arg2 ; this fails
DetailPrint "something: $arg1"
FunctionEnd
!macroend

!insertmacro myfunc ""
!insertmacro myfunc "un."


I've tried ${un}${ThirdPartyMacro}, ${${un}ThirdPartyMacro} and ${un.ThirdPartyMacro}, and none of them work. The weird thing is that "un.ThirdPartyMacro" is actually defined in the third party nsh file.

Thanks!
Mitch

it would you know, help if you said the name of the macro, but, the nsh probably has so way to define the uninstall macro


In one case it's a function from the StrFunc.nsh. Using ${StrRep} in the install function, and ${UnStrRep} in the separate uninstall function works, but that's the only difference in an otherwise lengthy function, which I would like to maintain only one copy of.

In the second case, I turned the code from here: http://nsis.sourceforge.net/REG_MULTI_SZ_Reader, into a nsh file, and defined 2 macros, ReadRegMulti & un.ReadRegMulti. I'm certainly willing to entertain the notion that I didn't set it up correctly, given my lack of understanding of the NSIS scripting language, so any help in configuring it correctly would be swell!


; with respect to KiCHiK

!ifndef ReadRegMulti
!define ReadRegMulti "!insertmacro ReadRegMulti"

!define HKEY_CLASSES_ROOT 0x80000000
!define HKEY_CURRENT_USER 0x80000001
!define HKEY_LOCAL_MACHINE 0x80000002
!define HKEY_USERS 0x80000003
!define HKEY_PERFORMANCE_DATA 0x80000004
!define HKEY_PERFORMANCE_TEXT 0x80000050
!define HKEY_PERFORMANCE_NLSTEXT 0x80000060
!define HKEY_CURRENT_CONFIG 0x80000005
!define HKEY_DYN_DATA 0x80000006

!define KEY_QUERY_VALUE 0x0001
!define KEY_ENUMERATE_SUB_KEYS 0x0008

!define REG_NONE 0
!define REG_SZ 1
!define REG_EXPAND_SZ 2
!define REG_BINARY 3
!define REG_DWORD 4
!define REG_DWORD_LITTLE_ENDIAN 4
!define REG_DWORD_BIG_ENDIAN 5
!define REG_LINK 6
!define REG_MULTI_SZ 7

!define RegOpenKeyEx "Advapi32::RegOpenKeyExA(i, t, i, i, *i) i"
!define RegQueryValueEx "Advapi32::RegQueryValueExA(i, t, i, *i, i, *i) i"
!define RegCloseKey "Advapi32::RegCloseKeyA(i) i"


!macro ReadRegMulti ResultVar HKEY KeyName Key
Push `${HKEY}`
Push `${KeyName}`
Push `${Key}`
Call ReadRegMulti
Pop `${ResultVar}`
!macroend

!macro un.ReadRegMulti ResultVar HKEY KeyName Key
Push `${HKEY}`
Push `${KeyName}`
Push `${Key}`
Call ReadRegMulti
Pop `${ResultVar}`
!macroend


Function ReadRegMulti

;Get input from user
Pop $R3 # "Strings"
Pop $R2 # "Software\Joe Software"
Pop $R1 # ${HKEY_CURRENT_USER}

StrCpy $0 ""
StrCpy $1 ""
StrCpy $2 ""
StrCpy $3 ""
StrCpy $9 ""

SetPluginUnload alwaysoff
System::Call "${RegOpenKeyEx}($R1, '$R2', 0, ${KEY_QUERY_VALUE}|${KEY_ENUMERATE_SUB_KEYS}, .r0) .r3"

StrCmp $3 0 goon
StrCpy $9 "Can't open registry key! ($3)"
Goto done
goon:

System::Call "${RegQueryValueEx}(r0, '$R3', 0, .r1, 0, .r2) .r3"

StrCmp $3 0 read
StrCpy $9 "Can't query registry value size! ($3)"
Goto done

read:

StrCmp $1 ${REG_MULTI_SZ} multisz
StrCpy $9 "Registry value no REG_MULTI_SZ! ($3)"
Goto done

multisz:

StrCmp $2 0 0 multiszalloc
StrCpy $9 "Registry value empty! ($3)"
Goto done

multiszalloc:

System::Alloc $2
Pop $1

StrCmp $1 0 0 multiszget
StrCpy $9 "Can't allocate enough memory! ($3)"
Goto done

multiszget:

System::Call "${RegQueryValueEx}(r0, '$R3', 0, n, r1, r2) .r3"

StrCmp $3 0 multiszprocess
StrCpy $9 "Can't query registry value data! ($3)"
Goto done

multiszprocess:

StrCpy $4 $1

IntOp $6 $4 + $2
IntOp $6 $6 - 1

#loop:

System::Call "*$4(&t${NSIS_MAX_STRLEN} .r3)"
#DetailPrint $3
Push $3

#StrLen $5 $3
#IntOp $4 $4 + $5
#IntOp $4 $4 + 1
#IntCmp $4 $6 0 loop

done:
DetailPrint $9

System::Free $1

StrCmp $0 0 noClose
System::Call "${RegCloseKey}(r0)"

noClose:

SetPluginUnload manual
FunctionEnd

!endif