Skip to content
⌘ NSIS Forum Archive

macro within a macro

3 posts

mstone42#

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
Anders#
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
mstone42#
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