Topic 3.3

Windows Registry

Working with the Windows Registry

The Windows Registry is used to store information and configuration settings for software, hardware devices, user preferences, operating system configurations, and much more. For example, when a new program is installed, a new set of instructions and file references may be added to the registry in a specific location for the program, and others that may interact with it, to reference from it information like where the files are located, which options to use in the program, and so on.

It's not necessary for all applications to utilize the Windows Registry. There are some programs that store their configurations in XML files instead of the registry, and others that are entirely portable and store their data in an executable file.
General Tips

Below I have put together certain ideas I find to be good practice in which you should try to implement when using custom.nsh. These are just some code snippets for general use which should make your life easier. First, I'd like to outline some things you should be aware of when using the registry while making a portable application with NSIS.

  • HKLM is for values that affect all users on the host computer.
  • HKCU is for values that affect only the current user on the host computer.
  • You do not need to be elevated to write under HKCU but you do need administrative rights when writing to HKLM; this doesn't include reading from HKLM.
  • Be aware of Registry Redirection as this is a common mistake when trying to read/write to/from the registry.
Registry Reading

It's usually a good idea to check for errors when reading from the registry. For example:

Var Owner
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "RegisteredOwner"
${If} ${Errors}
	MessageBox MB_OK "The key you are looking for does not exist.$\r$\n$\r$\nValue not found."
	${If} $0 == ""
		MessageBox MB_OK "The key exists but the value is empty."
		StrCpy $Owner $0 # Now the variable $Owner is set to whatever $0's value is.
Registry Writing

When using WriteRegDWORD, it is better to use something like 0x00000409 than it is to use 409. However, when using [RegistryValueWrite] in the Launcher.ini file it is better to use the decimal number system and not the hexadecimal number system. In the example below we're using two different methods to write the same value to the same key using this idea:

;= Using WriteRegDWORD in custom.nsh
WriteRegDWORD HKLM "SOFTWARE\Company\Program\Settings" "Language" 0x00000409

;= Using [RegistryValueWrite] in Launcher.ini
If you're using Notepad++, there's a plugin called TextFX which has many useful features—one of them being able to convert to and from decimal and hexadecimal numbers.
Registry Redirect

There is no 64-bit NSIS installer which means your launcher will always be a 32-bit process when running on 64-bit PC. This means that 32-bit redirection will take place. On Windows x64 the registry redirectorYou can find more details on this topic by reading this article. ensures that 32-bit applications which try to access their sections of the registry (e.g. HKLM\Software\Classes) actually get redirected to the corresponding entries in the Wow6432Node sub-tree. Similarly, the file-system redirector ensures that 32-bit applications which try to access the Program Files folder are redirected to Program Files (x86) instead. This is discussed in the next topic in greater detail.

So if a 32-bit installer tries to install a 64-bit application, the files and registry keys will end up in the wrong places. However, a 32-bit application can read and write to a 64-bit registry node by using SetRegView.

; SetRegView 32|64|lastused
; Below will set $0 to contain 'C:\Program Files (x86)'
SetRegView 32
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion" "ProgramFilesDir"
MessageBox MB_OK "$$0 is set to:$\r$\n$0"
; Below will set $0 to contain 'C:\Program Files'
SetRegView 64
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion" "ProgramFilesDir"
MessageBox MB_OK "$$0 is set to:$\r$\n$0"
SetRegView lastused # Sets back to the default view (32-bit in this case)
This page is unfinished and is still being written.
More to come soon.