Archive: Parseing regkey


Parseing regkey
  Hi, I am new to NSIS, I have a basic installer working that installs and uninstalls, so I have that working.

My current question comes to this:

What I am trying to write an installer for is a mod for a different program. So I want it to search the registry for its install path and install it there.

I know that there is the option to search for install path in an example, but my problem is, what do I do if the key can be stored in multiple places, IE its different on XP, Vista/7, and via two different methods, one is digital distribution, one is actual cd, so install keys are dif.

Can anyone point me in the right direction? :)

Thank you in advance.


I think you have to test all the places based on your conditions.

GetVersion:WindowsName (or whatever will work for you)

${If} $Version == xx
do what you have to

etc


Problem with that is XP would have two separate locations.
Vista/7 would have two separate locations.

Cd vs Digital Distribution.


Check both.
If you find the CD Key do what you need to.
Else look for the Digital Key

There is no magic bullet here.
I have to do similar stuff sometimes the key is in HKLM sometime HKCU might depend how something was installed.

It's not always pretty.
ReadRegStr ....
IfErrors KeyNotFound KeyFound


I found this code on the wiki:

Function GetCurrentAutoCADKey
;// =====================================================================
;// Construct a product key for the last AutoCAD run or installed.
;// This is referred to as the "Primary" AutoCAD. All CLSID entries
;// and path references in the registry should be consistent with this
;// entry.
;// Parameters
;// $1 Upon successful return
;// this will contain the fully qualified key that
;// will be found under HKEY_LOCAL_MACHINE
;// $2 Upon successful return
;// will contain the ACAD-ID InstallId
;// $3 Upon successful return
;// this will contain the path to acad.exe that is
;// associated with the current AutoCAD.
;// =====================================================================
;// Inspect the CurVer value at the ..\AutoCAD level to
;// determine the major release version key. This will
;// point us to a section in the registry based upon the
;// version number.
ReadRegStr $1 HKLM "Software\Autodesk\AutoCAD" "CurVer"
;// Must have the release version
IfErrors 0 NoError1
Goto Error
NoError1:
;// Inspect the CurVer value at the ..\AutoCAD\szKey level to
;// determine the registry key id. This will point us to a
;// major registry key where the Applications Subkey can be found
ReadRegStr $2 HKLM "Software\Autodesk\AutoCAD\$1" "CurVer"
;// Must have the ID
IfErrors 0 NoError2
StrCpy $1 ""
Goto Error
NoError2:
ReadRegStr $3 HKLM "Software\Autodesk\AutoCAD\$1\$2" "AcadLocation"
;// Must have the Path
IfErrors 0 NoError3
StrCpy $1 ""
StrCpy $2 ""
Goto Error
NoError3:
Error:
FunctionEnd

So what I'm understanding here is, I could modify this code to search one location, if it errors out, move along to the next? and just have nested ifs?

Along these lines:

ReadRegStr $1 HKLM "Software\Maker\Program" "Install_dir"

if errors 0 install_dir = $1
goto test2

test2:
ReadRegStr $1 HKLM "Software\wow64\Maker\Program" "Install_dir"
if errors 0 install_dir = $1
goto test3


and so on?


I always simply do:

ReadRegStr$1 HKLM "location1"

>${If} $1 == ""
ReadRegStr $1 HKLM "location2"
>${EndIf}
${If} $
1 == ""
ReadRegStr $1 HKCU "location3"
>${EndIf}
etc.

The code in the wiki is EXACTLY what you want.

Look up IfErrors.

You are messing with the proper syntax in your example.

IfErrors jumpto_iferror [jumpto_ifnoerror]

so yours might be something like
IfErrors 0 KeyFound

.... keep checking

KeyFound: (this is the jump label)
do what you need to.


Okay thank you for your help, I will give it a whack in a few and post back if my code isn't working :)


Get familiar with LogicLib if you are not.

You can write nicer code.

You MIGHT even be able to write

ReadRegStr ...
${If} {Errors}
;not found

${EndIf}

Not sure if this will work but it looked like it might and would be better than writing in jumps.


sorry

${If} ${Errors}


okay, having issues using the information to do anything productive. How do I tell it to use this for the installdirectory?

Installdir cant be composed in a section, and readregkey cant be used outside of one.


I use InstallDir just as like a default.

I use a variable called $INSTDIR - i set that

in your sections

SetOutPath $INSTDIR


Actually, what he needs is StrCpy $INSTDIR $1 (assuming $1 contains the path read from registry). You can of course also just ReadRegStr into $INSTDIR directly.

To elaborate on my earlier post, it's often advantageous to use ${If} $1 == "" instead of ${If} ${Errors}, because the error flag will only be set if the regkey doesn't exist. If the regkey does exist but is empty for some reason, you'll end up with an empty install path and you're still in trouble.


I ended up doing it like this, seems working so far.

Function .onInit ; Performed on start of the installer.
; Check for ArmA2 Steam install on Windows XP Via Steam
ReadRegStr $INSTDIR HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 33900" "InstallLocation"
IfErrors abort end
Goto end

; Check for ArmA2 Steam install on Vista/7 Via Steam
ReadRegStr $INSTDIR HKLM "SOFTWARE\Wow6432Node\Bohemia Interactive Studio\ArmA 2" "Main"
IfErrors abort end
Goto end

abort:
Abort

end:
FunctionEnd


ReadRegStr $INSTDIR HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 33900" "InstallLocation"
IfErrors abort end
Goto end you will never perform the next test

; Check for ArmA2 Steam install on Vista/7 Via Steam
ReadRegStr $INSTDIR HKLM "SOFTWARE\Wow6432Node\Bohemia Interactive Studio\ArmA 2" "Main"
IfErrors abort end
Goto end

abort:
Abort

end:
FunctionEnd


Weird that you say it wouldn't go to next test, as it did work on my actual machine detecting the correct install path. Any ideas what would cause it to work?

I 100% see why you say it wont, and will fix it later on today, just confused as to why it does lol.


Actually that line I highlighted would never get hit due to

IfErrors abort end

If there is an error - reg key not found you are going to abort
else you are going to end.

IfErrors 0 end might be better and get rid of that goto end

Are you just passing the first condition on your machine perhaps???


Nope I have virtualmachines to test each case. I modified the code to:

Function .onInit ; Performed on start of the installer.
; Check for ArmA2 Steam install on Windows XP Via Steam
ReadRegStr $INSTDIR HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 33900" "InstallLocation"
IfErrors steamvista end

steamvista:
; Check for ArmA2 Steam install on Vista/7 Via Steam
ReadRegStr $INSTDIR HKLM "SOFTWARE\Wow6432Node\Bohemia Interactive Studio\ArmA 2" "Main"
IfErrors abort end

abort:
Abort

end:
FunctionEnd