- NSIS Discussion
- Parseing regkey
Archive: Parseing regkey
Mik0z
22nd October 2009 18:52 UTC
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.
msroboto
22nd October 2009 19:46 UTC
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
Mik0z
22nd October 2009 19:52 UTC
Problem with that is XP would have two separate locations.
Vista/7 would have two separate locations.
Cd vs Digital Distribution.
msroboto
22nd October 2009 20:05 UTC
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
Mik0z
22nd October 2009 20:16 UTC
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?
MSG
22nd October 2009 20:23 UTC
I always simply do:
ReadRegStr$1 HKLM "location1"
>${If} $1 == ""
ReadRegStr $1 HKLM "location2"
>${EndIf}
${If} $
1 == ""
ReadRegStr $1 HKCU "location3"
>${EndIf}
etc.
msroboto
22nd October 2009 20:25 UTC
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.
Mik0z
22nd October 2009 20:31 UTC
Okay thank you for your help, I will give it a whack in a few and post back if my code isn't working :)
msroboto
22nd October 2009 20:38 UTC
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.
msroboto
22nd October 2009 20:39 UTC
sorry
${If} ${Errors}
Mik0z
22nd October 2009 22:00 UTC
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.
msroboto
23rd October 2009 06:15 UTC
I use InstallDir just as like a default.
I use a variable called $INSTDIR - i set that
in your sections
SetOutPath $INSTDIR
MSG
23rd October 2009 07:14 UTC
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.
Mik0z
23rd October 2009 16:52 UTC
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
msroboto
23rd October 2009 19:12 UTC
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
Mik0z
23rd October 2009 19:26 UTC
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.
msroboto
23rd October 2009 20:35 UTC
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???
Mik0z
23rd October 2009 22:10 UTC
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