Here goes obligatory "I love NSIS!" :). It is great! I tried several tools and this one is the best for small downloadable components. It is lightweight, feature rich, easy to use for developer, and intuitive for end user. Did I mention it produces really small code? ;)
Now it goes.
Win2k/WinXP has a significant change in registry handling: HKLM/HKCU pairing is introduced. MSDN article The HKEY_CLASSES_ROOT Key shows how it is done (automatically) for HKCR.
Some other parts of HKLM/HKCU are paired as well. The idea is: if user doesn't have permission to change HKLM entries, he/she can do it in HKCU. In this case it will be introduced on per user basis instead of global change.
E.g., it is possible to set up ActiveX for specific user without admin privileges (==poor corporate user). All you got to do is to use HKCU\Software\Classes instead of HKLM/Software/Classes and so on. Well, it is covered by HKCR.
The same goes for Uninstall information. Use HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall instead of HKLM\ditto. It works all right on Win2k/WinXP. It works (?!) on NT4. It doesn't work on Win9X (95-ME).
Problem: I need some way to fall back to HKCU root, if I was not able (OS limitation? security? user's desire?) to use HKLM.
Q&D solution I made: I wrote a program, which creates file, if there is no corresponding key in HKLM and we are running Win2k/WinXP. I use it like this:
; Cleanup uninstall registry
DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\
Uninstall\Sample"
DeleteRegKey HKEY_CURRENT_USER "Software\Microsoft\Windows\CurrentVersion\
Uninstall\Sample"
; Write uninstall registry
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\
Uninstall\Sample" "DisplayName" "Sample"
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\
Uninstall\Sample" "UninstallString"
'"$INSTDIR\uninstall.exe"'
; work around Win2k/WinXP security
SetOutPath "$TEMP"
File Reg2K.exe
ExecWait '"$TEMP\Reg2K.exe" Sample "$TEMP\sample.flag"'
Delete "$TEMP\Reg2K.exe"
IfFileExists "$TEMP\sample.flag" 0 3
WriteRegStr HKEY_CURRENT_USER "Software\Microsoft\Windows\CurrentVersion\
Uninstall\Sample" "DisplayName" "Sample"
WriteRegStr HKEY_CURRENT_USER "Software\Microsoft\Windows\CurrentVersion\
Uninstall\Sample" "UninstallString"
'"$INSTDIR\uninstall.exe"'
Delete "$TEMP\sample.flag"
Nop
Something like that. Drawbacks of this solution: It is inelegant, it carries extra code, if tomorrow I need to pair other parts of registry, I need to enhance my program, when my program starts it flickers (?). I would prefer to use scripting to do checking.
Proposal #1: make OS version available to script.
Proposal #2: make available status of last WriteRegStr operation.
Proposal #3: we need some way to test registry keys for existence.
Question: is it possible to run programs in background without showing window? It should be an argument of Exec/ExecWait.
Maybe it is resolved already in upcoming versions.
Thanks,
Uhop