Archive: User variable problem - sometimes works and sometimes doesn't


User variable problem - sometimes works and sometimes doesn't
Hello NSISers!

I'd like to discuss decent problem. I've put the "registry" part of my install script into separate file (e.g. registry.nsi). That file is !included in my "main" .nsi file. I use function ZapisRegistry to do all the reg's work.

Main script:


...
Section Install
...
Call ZapisRegistry
...
SectionEnd
...

Auxiliary script:

!macro ZapisReg type root hive key value
...
!macroend
...
Var AktualniKlic
Function ZapisRegistry
...
StrCpy $AktualniKlic "Software\Microsoft" ; i am not a M$ guy
MessageBox MB_OK $AktualniKlic ; JUST TO BE SURE
...
; REGISTRY WORKAROUND
FunctionEnd
...

Now, everything works OK.

But if I add ANOTHER ONE macro into my auxiliary script, the variable $AktualniKlic will be empty after the StrCpy instruction.

What am I doing wrong? :(

PS: "Zapis" means something like "Write" ;)

Another problem
The previously mentioned function "ZapisRegistry" looks like this:


MessageBox MB_OK "Registry start"

!insertmacro ZapisReg ...
!insertmacro ZapisReg ...
!insertmacro ZapisReg ...

MessageBox MB_OK "Phase 1 completed"
!insertmacro ZapisReg ...

MessageBox MB_OK "Phase 2 completed"
!insertmacro ZapisReg ...

...

Problem is, that only the FIRST MessageBox instruction works. Any relation with that macros? :weird:

What does the ZapisReg macro contain?

Stu


ZapisReg
Saying Hi! from Czech Republic to England Stu!


!macro ZapisReg type root hive key value
ClearErrors
StrCmp ${type} 'str' 0 +2
WriteRegStr '${root}' '${hive}' '${key}' '${value}'
StrCmp ${type} 'dword' 0 +2
WriteRegDword '${root}' '${hive}' '${key}' '${value}'
IfErrors 0 +3
MessageBox MB_ICONEXCLAMATION|MB_OK "ERRRORRR!"
; Abort "Chyba - neni pristup k registrum"
!macroend

The second macro should contain something like:

!macro CteniReg type variable root hive key silent
ClearErrors
StrCmp ${type} 'str' 0 +2
ReadRegStr ${variable} '${root}' '${hive}' '${key}'
StrCmp ${type} 'dword' 0 +2
ReadRegDWORD ${variable} '${root}' '${hive}' '${key}'
IfErrors 0 +3
IntCmp ${silent} 1 +2 0
MessageBox MB_ICONEXCLAMATION|MB_OK "ERRRORRR!"
;Abort "Chyba - neni pristup k registrum"
!macroend


Do you think that this makes the bug?

BTW: This is not the only mystical behavior of NSIS that I noticed today. E.g. I compiled script and after runnig it, the script executed some function ITSELF, then I added one debug MessageBox and everything behaves normally, even if I remove the MB and compile again... No conditional jumps involved. I am being little bit confused from NSIS today.

Hey!

!macro ZapisReg type root hive key value
ClearErrors
StrCmp ${type} 'str' 0 +2
WriteRegStr '${root}' '${hive}' '${key}' '${value}'
StrCmp ${type} 'dword' 0 +2
WriteRegDword '${root}' '${hive}' '${key}' '${value}'
IfErrors 0 +3
MessageBox MB_ICONEXCLAMATION|MB_OK "ERRRORRR!"
; Abort "Chyba - neni pristup k registrum"
!macroend


IfErrors 0 +3 ;This statement is wrong

it should be

IfErrors 0 +2 ;This statement is right

Since you are jumping to the wrong location this program would behave abnormally.

I hope this helps


Jumps
I cannot jump to !macroend line?

And can I jump to commented line?


I think you can jump to a !macroend. Have you tried it?
No, you cant jump to a commented line

+1 - this means goto the next instruction
+2 - this means goto the next next instruction

and so on.

Just give it a try.


Use goto labels instead of instruction numbers jumps - far less confusing.


!macro ZapisReg type root hive key value
ClearErrors
StrCmp ${type} 'str' 0 +2
WriteRegStr '${root}' '${hive}' '${key}' '${value}'
StrCmp ${type} 'dword' 0 +2
WriteRegDword '${root}' '${hive}' '${key}' '${value}'
IfErrors 0 ZapisReg_End
MessageBox MB_ICONEXCLAMATION|MB_OK "ERRRORRR!"
; Abort "Chyba - neni pristup k registrum"
ZapisReg_End:
!macroend

thank you all!

but I think, that using labels in macros isn't good idea. what if the macro will be called more than 1 time?


UniqueID
One way round this is to define a "UniqueID" as in here: http://nsis.sourceforge.net/Tutorial...s_in_macro%27s

The only flaw is if you use one macro inside another that both define this UniqueID. To get around that, I just prepend the name of the macro like this:


!macro ZapisReg type root hive key value
!define ZapisReg_UniqueID ${__LINE__}
ClearErrors
StrCmp ${type} 'str' 0 +2
WriteRegStr '${root}' '${hive}' '${key}' '${value}'
StrCmp ${type} 'dword' 0 +2
WriteRegDword '${root}' '${hive}' '${key}' '${value}'
IfErrors 0 ZapisReg_End_${ZapisReg_UniqueID}
MessageBox MB_ICONEXCLAMATION|MB_OK "ERRRORRR!"
; Abort "Chyba - neni pristup k registrum"
ZapisReg_End_${ZapisReg_UniqueID}:
!undef ZapisReg_UniqueID
!macroend


Not very nice, I know, but sometimes the only way to do it.

impressive
that seems nice, but I will do with the line-skip method

but thank you DrDan, you seem like hardcore NSISer ;-)


No point using labels here. Things to remember with relative jumps...

They jump over real instructions only, not compile time ones such as !define or !insertmacro.
They do not take into account blank lines or comments (why should it?)

This will not work as expected:
!macro blah
Sleep 1000
Sleep 1000000
!macroend

Goto +2
!insertmacro blah

This will skip Sleep 1000 but not Sleep 1000000.

Stu