Archive: IfKeyExists??


IfKeyExists??
  Is there a built-in function for "IfKeyExists"? If not, I think I'm going to attempt to make a function for that...and maybe others would like it as well. But, remember, I'm a beginner, so my way may not be the best way......it will just be A way. Thanks!


No I don't think that there is a function for this. You might find EnumRegKey usefull in creating that function.

Vytautas

BTW If you need any help in creating it just ask;)


I looked into creating IfKeyExists, but it looks like it's only worth making if it can be a built-in function...like IfFileExists...at least from what I know.

In other words, WITHOUT being a built-in function, the call would look like this:
Push $0
Push $1
Push $2
Push $3
Push $R0 'Return Value
Call IfKeyExists
Pop $3
Pop $2
Pop $1
Pop $0
StrCmp $R0 "" 0 ItExists
MessageBox "Key Does Not Exist"
GoTo Done
ItExists:
MessageBox "Key Exists"
Done:
Pop $R0

Or, you could simply use (I think this is how it's used):
Push $R0
EnumRegKey $R0 HKCU "Software\Package" "Version" "0"
StrCmp $R0 "" 0 ItExists
MessageBox "Key Does Not Exist"
GoTo Done
ItExists:
MessageBox "Key Exists"
Done:
Pop $R0

OR...if it were built-in:
IfKeyExists HKCU "Software\Package" "Version" 0 ItExists
MessageBox "Key Does Not Exist"
GoTo Done
ItExists:
MessageBox "Key Exists"
Done:

What does everyone else think???


I created a macro to do this, well almost, you can find it here. After you insert this macro you should pop the result of the stack and check to see if it was found.

I tried to create a macro which can jump to a label depending on the result however I could not figure out how to make the last parameter of the macro optional, any ideas?

Hope this helps, BTW your code for EnumRegKey would not work, it will generate an infinate loop, you should increment the index every time you check for the next key.

Vytautas


There's an error.
You have used Found for a jump instead of FoundMe

-Stu


What do yo umean by this?

I tried to create a macro which can jump to a label depending on the result however I could not figure out how to make the last parameter of the macro optional, any ideas?

-Stu


I tried this code and it worked but only if both labels are specified

!insertmacro IfKeyExists "ROOT" "KeyToCheckIn" "KeyToCheck" "GOTO_Here_IF_FOUND" "GOTO_Here_IF_NOT_FOUND"
I would like the last label to be optional like in similar function calls.

Vytautas

Originally posted by Afrow UK
There's an error.
You have used Found for a jump instead of FoundMe

-Stu
Thanks, fixed that error.

:o Vytautas :o

Ah I don't really know.
I didn't even know you could do jumps with InsertMacro's!

-Stu


I'm not sure you're supposed to but I tried and jumps to labels seemed to work. Relative jumps would need heavy modification so probably are not a good idea. You see the jumps work because !insertmacro code just does a copy&paste of the macro into the script, not literally but effectively.

Vytautas


Ah yes I was thinking about that.
Also, surely if you wanted people to use your code more than once in the same script then you should gave each label a specific name eg.

FoundMe${BLAH}

Have a look at how Modern UI uses Macro's and maybe that will help you find it out.

-Stu


Thanks, I didn't think to test this macro more than once in the script.

Vytautas


Is there a built-in function for "IfKeyExists"?
Wouldn't this do the job?
ClearErrors

ReadINIStr$4 "$EXEDIR\\Settings.ini" "Settings" "Search String"
>IfErrors "" cont
MessageBox MB_OK`problems, problems!`
>cont:
changing the ini for the registry

Not quite, your solution will work with values NOT keys.

Vytautas


keys means branches, isn't it?

in that case you can check for the default value every key has, isn't it?


Yes, but most registry keys have blank, not set, dafault values so that function would not find those keys.

Vytautas


mmmm... I suppose that blank default values don't set the error flag to true.

mmmm... I tested with this existant and empty key and doesn't report an error

  ClearErrors

ReadRegStr$5 HKCR ".art\\ShellEx" ""
Iferrors "" noter
MessageBox MB_OK "error"
noter:

I tried both your code and the following code to a key that does not exist and both showed the message box.

ClearErrors
ReadRegStr $5 HKCR ".art\ShellEx.test" ""
Iferrors "" noter
MessageBox MB_OK "error"
noter:
It seems to me that the error flag is set if the value is not set and also if the value does not exist and is therefore not very usefull for the function we need here.

Vytautas

oh, I don't understand now.

In my computer if the "(Default)" value is "(value not set)" then the messagebox it's not showed.

I am using win98se and I attach a snapshot of the registry when I use that piece of code.


The error flag is set for ReadRegStr when the key can not be opened (security, not found or anything else), the value doesn't exist or can't be queried (again security, not found or anything else) or if the type of the value is wrong (not of type string).


sorry, I read this many times, and can't conclude if the idea I give is valid or not.

It's still seems to me that is valid.


This below isn't sufficient to do it? (I don't know if the code below works because I don't have a personal computer, nor NSIS)

EnumRegKey $0 HKLM "Software/NSIS" 0
IfErrors 0 +3
StrCpy $0 0
Goto +2
StrCpy $0 1


Please, someone test it.

deguix, the last parameter of the EnumRegKey is the index of the entry to check and thus it should be incremented otherwise it will either only check the first key or create an infinate loop.

So the last '0' should be replaced with a variables which is incremented until the required key is found or all of the keys are search through.

Vytautas


You want to know if have keys inside the key, or want to know if it exist or not?

(hey, my signature style is being copied by some users in this forum! My signature is going to be famous by this way!)


So does the EnumRegKeys function return the root key before it's subkeys? I did not find that in the documentation & can not check you code at this moment. Will get back as soon as I can check it out although I dought it will work as expected.

Vytautas

PS Your idea for the signiture was really good. Thanks ;)


ok, I am completely lost on this subject.


Doesn't the function in my archive pages work for you???

Vytautas


Typo in your macro Vytautas...
  Right after the EnumRegKey call you put a colon on the goto label, which causes a 'couldn't resolve the label' compile-time error.


"${Index}-Loop:"
; Check for Key
EnumRegKey $R0 ${ROOT} "${MAIN_KEY}" "$R1"
StrCmp $R0 "" "${Index}-False:"


that StrCmp line should read ...

StrCmp $R0 "" "${Index}-False"


I like your method, but it doesn't seem to work for me -- I haven't had luck with EnumRegKey and ReadRegStr either. Here's an example where I use a key that I know exists (looking at it in RegEdit):


Function Sample
!insertmacro KeyExists HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Adobe Acrobat 5.0" "DisplayName"
Pop $R0
IntCmp $R0 0 EndSample EndSample 0

;...code to handle stuff when we find the key ...
MessageBox MB_OK "Wow it found it!"

EndSample:
FunctionEnd


... I never see the dialog box, even though I know the key exists. I figure that at least 1 other person in this forum will have Acrobat 5 (reader) installed, so if you can make the above code work on your system as-is then my machine is horked somehow. If there's a mistake, please let me know where I went wrong!

NSIS 2.0b4, Win2K Pro ...

Thanks!!

AnalogKid
=^{D}

Originally posted by Vytautas
Doesn't the function in my archive pages work for you???

Vytautas
Oh, sorry, I didn't read your reply. I was lost on the discussion, I haven't tried your function.

I just couldn't understand why my idea does not work. :mad: :weird:

Right after the EnumRegKey call you put a colon on the goto label, which causes a 'couldn't resolve the label' compile-time error.
Thanks, fixed.

As for the other problem. 'DisplayName' is NOT a key, keys appear as folders in regedit, so thats why the function does not work.

Vytautas

Yes, sorry, I figured out what was wrong right about the same time I woke up and went home ... EnumRegValue is what I really wanted rather than EnumRegKey ;-)

Thanks for the cool fn/macro and the ideas with the self-generating labels. I've never tried that before -- didn't know it would work ;-)

I love these forums ... I get so much inspiration sometimes just by glancing through 'em!

AnalogKid
=^{D}


Originally posted by Vytautas
As for the other problem. 'DisplayName' is NOT a key, keys appear as folders in regedit, so thats why the function does not work.
I still don't understand.

ClearErrors
ReadRegStr $5 HKCR ".art\ShellEx.test" ""
Iferrors "" noter
MessageBox MB_OK "error"
noter:

This checks for the "(Default)" name which something every key (folder ;)) has.

The only fault I can imagine is what kichik says: that the error flag could be triggered when it can't be opened because of security or can't be queried.

Although every key has that entry it is not set, e.g. is Null, and therefore NSIS sets the error flag as if the entry did not exist.

Vytautas


Why doesn't this code work?
  Hi,

I try to use your macro to check for a certain registry key, this is my code:

[...]
;Check if the standard Cygwin Registry keys exist (x32)
!insertmacro IfKeyExists HKLM "SOFTWARE\Cygnus Solutions\Cygwin\mounts v2" "cygdrive flags"
Pop $R0
IntCmp $R0 0 DoInstall ByReg ByReg
;Check if the standard Cygwin Registry keys exist (x64)
!insertmacro IfKeyExists HKLM "SOFTWARE\Wow6432Node\Cygnus Solutions\Cygwin\mounts v2" "cygdrive flags"
Pop $R0
IntCmp $R0 0 DoInstall ByReg ByReg

;This is the label to jump to if a registy key is found
ByReg:
MessageBox MB_ICONSTOP "RegistryKeys for Cygwin exist on this machine. Please first remove any installation of cygwin and then restart this installer..."
Quit

;This is the label to jump to if Cygwin is not installed yet.
DoInstall:
[...]

Why wouldn't it jump to ByReg if the key is found?

Please help - I'm lost...

Regards,

Chris


Quote:


you have 2 'ByReg'.

it should be:
IntCmp $R0 0 DoInstall ByReg


Also.. if you're checking x64 reg key.. use SetRegView 64.

Originally Posted by cherdeg (Post 2335486) Hi,

I try to use your macro to check for a certain registry key, this is my code:

[...]
;Check if the standard Cygwin Registry keys exist (x32)
!insertmacro IfKeyExists HKLM "SOFTWARE\Cygnus Solutions\Cygwin\mounts v2" "cygdrive flags"
Pop $R0
IntCmp $R0 0 DoInstall ByReg ByReg
;Check if the standard Cygwin Registry keys exist (x64)
!insertmacro IfKeyExists HKLM "SOFTWARE\Wow6432Node\Cygnus Solutions\Cygwin\mounts v2" "cygdrive flags"
Pop $R0
IntCmp $R0 0 DoInstall ByReg ByReg

;This is the label to jump to if a registy key is found
ByReg:
MessageBox MB_ICONSTOP "RegistryKeys for Cygwin exist on this machine. Please first remove any installation of cygwin and then restart this installer..."
Quit

;This is the label to jump to if Cygwin is not installed yet.
DoInstall:
[...]

Why wouldn't it jump to ByReg if the key is found?

Please help - I'm lost...

Regards,

Chris

And use LogicLib instead of IntCmp.

Stu