Archive: Wish registry functions worked with variables for rootkeys


Wish registry functions worked with variables for rootkeys
  I started to write this piece of code to decide which root key to use for storing certain configuration values in registry.


${If} $OSgen == "Win9x" ; Windows 95/98/ME
StrCpy $RootKey "HKLM"
${Else} ; WinNT/Win2000,WinXP
${Select} $UserRights
${Case2} "User" "Guest"
StrCpy $RootKey "HKCU"
${Case2} "Admin" "Power"
${If} ${Context} == "1" ; context selected during instalation, 1=All users, 0=Current user
StrCpy $RootKey "HKLM"
${Else}
StrCpy $RootKey "HKCU"
${EndIf}
${EndSelect}
${EndIf}

And I wanted to use it this way:

WriteRegStr $RootKey "Software\${Company}\${ProductName}" "Key1" "Value"

But finally I have found that registry functions don't accept variables for rootkey. So this is my feature suggestion for next version of NSIS.

Use quotes around $rootkey:

WriteRegStr "$RootKey" "Software\${Company}\${ProductName}" "Key1" "Value"


That won't help. Variables are not supported there.


And one more note:

It would be also nice if Start menu would support variable rootkey. Currently it is defined during compilation (!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM") and does not allow to set it in runtime based on user environment.


I created a macro for writing to the registry, in which I pass HKLM or HKCU depending and then reference it like a normal macro would. This appears to work fine for me.

!insertmacro Write2Reg "HKLM" "Software\MyCompany" "Chicken" "Egg"

!macro Write2Reg ROOT KEY NAME VALUE
WriteRegStr "${ROOT}" "${KEY}" "${NAME}" "${VALUE}"
!macroend


Are you saying, Joost, that this isn't supported?


I have not checked the details. It it works fine for you, you have found a way to avoid the check.


So should I change this, or will the above be supported?


If it works there is no need to change it.


zimsms,

your macro works, but it doesn't solve what I wanted. Macro only expands its definition during compilation, nothing more. I wanted to use variable (defined in runtime) for a root key. If I use your macro with variable ($R1):

!insertmacro Write2Reg $R1 "Software\MyCompany" "Chicken" "Egg"

it does not work and I get the same error during compilation:

Usage: WriteRegStr rootkey subkey entry_name new_value_string
root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)

because WriteRegStr function does not allow first parameter to be variable. Macro cannot change anything with this.


Ahh, sorry I missed that. I only needed to know at compile time. I agree that would be a nice feature request.


I did not check that code. It's indeed just a macro that is processed on compile-time.


Summarizing:

Macros parameters in which are used codes are like defines, it is like just putting another name to a variable, like:


Section


StrCpy $R0 Test
>!define TEST $R0
MessageBox MB_OK${TEST}

>SectionEnd
>
As the professional way to say it, when you use ${TEST} it is just linking to the buffer that contains the string, but not the string itself, so if a parameter doesn't support variables feature, it doesn't look inside that buffer for the string, it returns the variable name as a string (i.e. $R0).

I think I might have designed a macro that should fix your problem. If you could test the attached macro and if it works I shall convert all of the reg functions into similar macros.

Vytautas


Vytautas,

yes, it is a solution. I wrote something similar for HKLM and HKCU only. But the disadvantage of using macros is that each usage of your WriteRegStr macro (and I have lot of them) is expanded during compilation to 21 instructions. That's why I wrote my wish so some core NSIS developer could enable variable rootkey in WriteRegStr instruction.

Thanks anyway.