diff --git a/Docs/src/history.but b/Docs/src/history.but
index 4db08425..fec33ade 100644
--- a/Docs/src/history.but
+++ b/Docs/src/history.but
@@ -24,12 +24,14 @@ Released on ? ?th, 2020
\b MultiUser: Fixed INSTALLMODE_FUNCTION and added INSTALLMODEPAGE_SHOWUSERNAME
-\b Python 3 fixes (\W{http://sf.net/p/nsis/patches/296}{patch #296})
-
\S2{} Translations
\b Updated German (SebStange PR)
+\S2{} Build System
+
+\b Python 3 fixes (\W{http://sf.net/p/nsis/patches/296}{patch #296})
+
\H{v3.05} 3.05
Released on December 15th, 2019
diff --git a/Docs/src/usefulfunc.but b/Docs/src/usefulfunc.but
index be9647ff..582eb09f 100644
--- a/Docs/src/usefulfunc.but
+++ b/Docs/src/usefulfunc.but
@@ -2,102 +2,80 @@
\H{getieversion} Get Internet Explorer version
-\c ; GetIEVersion
-\c ;
-\c ; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/
-\c ; Returns 1-6 (IE Version) or '' (IE is not installed) on top of the stack
-\c ;
-\c ; Usage:
-\c ; Call GetIEVersion
-\c ; Pop $R0 ; at this point $R0 is "5" or whatnot
+\c ; GetIEVersion
+\c ;
+\c ; Returns 1-11 (IE Version) or '' (IE is not installed) on top of the stack
+\c ;
+\c ; Usage:
+\c ; Call GetIEVersion
+\c ; Pop $R0 ; $R0 is "5" etc.
\c
-\c Function GetIEVersion
-\c Push $R0
-\c ClearErrors
-\c ReadRegStr $R0 HKLM "Software\Microsoft\Internet Explorer" "Version"
-\c IfErrors lbl_123 lbl_456
-\c
-\c lbl_456: ; ie 4+
-\c Strcpy $R0 $R0 1
-\c Goto lbl_done
-\c
-\c lbl_123: ; older ie version
-\c ClearErrors
-\c ReadRegStr $R0 HKLM "Software\Microsoft\Internet Explorer" "IVer"
-\c IfErrors lbl_error
-\c
-\c StrCpy $R0 $R0 3
-\c StrCmp $R0 '100' lbl_ie1
-\c StrCmp $R0 '101' lbl_ie2
-\c StrCmp $R0 '102' lbl_ie2
-\c
-\c StrCpy $R0 '3' ; default to ie3 if not 100, 101, or 102.
-\c Goto lbl_done
-\c lbl_ie1:
-\c StrCpy $R0 '1'
-\c Goto lbl_done
-\c lbl_ie2:
-\c StrCpy $R0 '2'
-\c Goto lbl_done
-\c lbl_error:
-\c StrCpy $R0 ''
-\c lbl_done:
-\c Exch $R0
-\c FunctionEnd
+\c Function GetIEVersion
+\c Push $R0
+\c ReadRegStr $R0 HKLM "Software\Microsoft\Internet Explorer" "svcVersion" ; IE v10+
+\c StrCpy $R0 $R0 2
+\c IntCmp $R0 9 "" "" lbl_done
+\c ClearErrors
+\c ReadRegStr $R0 HKLM "Software\Microsoft\Internet Explorer" "Version" ; IE v4..9
+\c IfErrors lbl_123
+\c StrCpy $R0 $R0 1 ; Note: This truncates 5.50 to 5 etc.
+\c Goto lbl_done
+\c lbl_123:
+\c !if "${NSIS_PTR_SIZE}" > 4
+\c StrCpy $R0 ""
+\c !else
+\c ReadRegStr $R0 HKLM "Software\Microsoft\Internet Explorer" "IVer" ; IE v1..3
+\c IntCmp $R0 99 "" "" +3
+\c StrCpy $R0 ""
+\c Goto lbl_done
+\c IntOp $R0 $R0 & 3 ; 100..103->0..3
+\c IntCmp $R0 2 +2 "" +2
+\c IntOp $R0 $R0 + 1 ; Bump 100->v1 and 101->v2 (Is 101 v1.5 or 2.0?)
+\c !endif
+\c lbl_done:
+\c Exch $R0
+\c FunctionEnd
\H{detect.netframework} Is .NET Framework installed?
-\c ; IsDotNETInstalled
-\c ;
-\c ; Based on GetDotNETVersion
-\c ; http://nsis.sourceforge.net/Get_.NET_Version
-\c ;
-\c ; Usage:
-\c ; Call IsDotNETInstalled
-\c ; Pop $0
-\c ; StrCmp $0 1 found_dotNETFramework no_dotNETFramework
-\c
-\c Function IsDotNETInstalled
-\c Push $0
-\c Push $1
-\c
-\c StrCpy $0 1
-\c System::Call "mscoree::GetCORVersion(w, i ${NSIS_MAX_STRLEN}, *i) i .r1"
-\c StrCmp $1 0 +2
-\c StrCpy $0 0
-\c
-\c Pop $1
-\c Exch $0
-\c FunctionEnd
+\c ; IsDotNETInstalled
+\c ;
+\c ; NOTE: This is only able to detect .NET v1.x and v2.x!
+\c ;
+\c ; Based on GetDotNETVersion
+\c ; http://nsis.sourceforge.net/Get_.NET_Version
+\c ;
+\c ; Usage:
+\c ; Call IsDotNETInstalled
+\c ; Pop $0 ; 0 or 1
+\c ; StrCmp $0 1 found_dotNETFramework_v1_or_v2 no_dotNETFramework
+\c
+\c Function IsDotNETInstalled
+\c Push $0
+\c System::Call '"$SysDir\MSCOREE.dll"::GetCORVersion(w,i${NSIS_MAX_STRLEN},*i)i.r0?u'
+\c IntOp $0 $0 ! ; HRESULT (S_OK) -> BOOL
+\c Exch $0
+\c FunctionEnd
\H{isflashinstalled} Is Macromedia Flash Player installed?
-\c ; IsFlashInstalled
-\c ;
-\c ; By Yazno, http://yazno.tripod.com/powerpimpit/
-\c ; Returns the result on top of the stack
-\c ;
-\c ; Usage:
-\c ; Call IsFlashInstalled
-\c ; Pop $R0 ; $R0 is "1" or "0" at this point
+\c ; IsFlashInstalled
+\c ;
+\c ; Usage:
+\c ; Call IsFlashInstalled
+\c ; Pop $R0 ; 1 or ""
\c
-\c Function IsFlashInstalled
-\c Push $R0
-\c ClearErrors
-\c ReadRegStr $R0 HKCR "CLSID\{D27CDB6E-AE6D-11cf-96B8-444553540000}" ""
-\c IfErrors lbl_na
-\c StrCpy $R0 1
-\c Goto lbl_end
-\c lbl_na:
-\c StrCpy $R0 0
-\c lbl_end:
-\c Exch $R0
-\c FunctionEnd
+\c Function IsFlashInstalled
+\c Push $R0
+\c ReadRegStr $R0 HKCR "CLSID\{D27CDB6E-AE6D-11cf-96B8-444553540000}" ""
+\c StrCmp $R0 "" +2
+\c StrCpy $R0 "1"
+\c Exch $R0
+\c FunctionEnd
\H{connectinternet} Connect to the Internet
-\c ; ConnectInternet (uses Dialer plug-in)
-\c ; Written by Joost Verburg
+\c ; ConnectInternet (uses Dialer plug-in) - Written by Joost Verburg
\c ;
\c ; This function attempts to make a connection to the internet if there is no
\c ; connection available. If you are not sure that a system using the installer
@@ -118,7 +96,7 @@
\c Pop $R0
\c StrCmp $R0 "online" connected
\c MessageBox MB_OK|MB_ICONSTOP "Cannot connect to the internet."
-\c Quit ;This will quit the installer. You might want to add your own error handling.
+\c Quit ; This will quit the installer. You might want to add your own error handling.
\c
\c noie3:
\c
@@ -131,11 +109,6 @@
\c
\c FunctionEnd
-\H{installerfilename} Get Installer Filename
-
-\c System::Call 'kernel32::GetModuleFileName(p 0, t .R0, i ${NSIS_MAX_STRLEN}) i.r1'
-\c ;$R0 will contain the installer filename
-
\H{multipleinstances} Prevent Multiple Instances
Put the following code in your \R{oninit}{.onInit function}:
@@ -147,7 +120,7 @@ Put the following code in your \R{oninit}{.onInit function}:
\c MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running."
\c Abort
-'myMutex' must be replaced by a unique value!
+'myMutex' \e{must} be replaced by a unique string or GUID!
\H{morefuncs} More
diff --git a/Docs/src/usefulinfos.but b/Docs/src/usefulinfos.but
index dc109df8..46ade0cd 100644
--- a/Docs/src/usefulinfos.but
+++ b/Docs/src/usefulinfos.but
@@ -170,7 +170,6 @@ First you have to change the output directory to that where the DLL you want to
The following code fragment will install 'condmgr.dll' to a temporary directory, execute the CmGetHotSyncExecPath function and display returned data.
Save this script
-\c ; **** snip ****
\c Function loadDll
\c
\c SetOutPath $TEMP\eInspect ; create temp directory
@@ -182,7 +181,6 @@ Save this script
\c DetailPrint "Return value: $2"
\c
\c FunctionEnd
-\c ; **** snip ****
and this function produces the following output in the 'details' page:
@@ -194,11 +192,11 @@ Path length: 24 \\
Return value: 0
-Written by \W{http://nsis.sourceforge.net/archive/profile.php?userid=78}{djc}
+Written by \W{https://web.archive.org/web/2018/http://nsis.sourceforge.net/archive/profile.php?userid=78}{djc}
-\\Acknowledgements & Thanks\\ \\
-Lots of thanks go to \\kichik\\ and \\Sunjammer\\ for spending a lot of time assisting in solving this problem. Also to \\brainsucker\\ for creating the System.dll plug-in in the first place.
-Good Luck!
+\# \\Acknowledgements & Thanks\\ \\
+\# Lots of thanks go to \\kichik\\ and \\Sunjammer\\ for spending a lot of time assisting in solving this problem. Also to \\brainsucker\\ for creating the System.dll plug-in in the first place.
+\# Good Luck!
\H{dumplogtofile} Dump Content of Log Window to File
@@ -208,17 +206,24 @@ To use it, push a file name and call it. It will dump the log to the file specif
\c GetTempFileName $0
+\c DetailPrint "Writing log to $0"
\c Push $0
\c Call DumpLog
+If you're building a \R{intro-unicode}{Unicode installer} you can \cw{!define DumpLog_As_UTF16LE} to output as UTF-16LE or \cw{!define DumpLog_As_UTF16LE "/BOM"} to output as UTF-16LE with a BOM.
+
Here is the function:
-
-
-\c !define LVM_GETITEMCOUNT 0x1004
-\c !define LVM_GETITEMTEXTA 0x102D
-\c
-\c Function DumpLog # Written by KiCHiK
+\c !define /IfNDef LVM_GETITEMCOUNT 0x1004
+\c !define /IfNDef LVM_GETITEMTEXTA 0x102D
+\c !define /IfNDef LVM_GETITEMTEXTW 0x1073
+\c !if "${NSIS_CHAR_SIZE}" > 1
+\c !define /IfNDef LVM_GETITEMTEXT ${LVM_GETITEMTEXTW}
+\c !else
+\c !define /IfNDef LVM_GETITEMTEXT ${LVM_GETITEMTEXTA}
+\c !endif
+\c
+\c Function DumpLog
\c Exch $5
\c Push $0
\c Push $1
@@ -226,82 +231,29 @@ Here is the function:
\c Push $3
\c Push $4
\c Push $6
-\c
\c FindWindow $0 "#32770" "" $HWNDPARENT
\c GetDlgItem $0 $0 1016
-\c StrCmp $0 0 error
+\c StrCmp $0 0 exit
\c FileOpen $5 $5 "w"
-\c StrCmp $5 0 error
+\c StrCmp $5 "" exit
\c SendMessage $0 ${LVM_GETITEMCOUNT} 0 0 $6
-\c System::StrAlloc ${NSIS_MAX_STRLEN}
-\c Pop $3
+\c System::Call '*(&t${NSIS_MAX_STRLEN})p.r3'
\c StrCpy $2 0
-\c System::Call "*(i, i, i, i, i, i, i, i, i) p \
-\c (0, 0, 0, 0, 0, r3, ${NSIS_MAX_STRLEN}) .r1"
+\c System::Call "*(i, i, i, i, i, p, i, i, i) i (0, 0, 0, 0, 0, r3, ${NSIS_MAX_STRLEN}) .r1"
\c loop: StrCmp $2 $6 done
-\c System::Call "User32::SendMessageA(p, i, p, p) i \
-\c ($0, ${LVM_GETITEMTEXTA}, $2, r1)"
+\c System::Call "User32::SendMessage(i, i, i, i) i ($0, ${LVM_GETITEMTEXT}, $2, r1)"
\c System::Call "*$3(&t${NSIS_MAX_STRLEN} .r4)"
-\c FileWrite $5 "$4$\r$\n"
+\c !ifdef DumpLog_As_UTF16LE
+\c FileWriteUTF16LE ${DumpLog_As_UTF16LE} $5 "$4$\r$\n"
+\c !else
+\c FileWrite $5 "$4$\r$\n" ; Unicode will be translated to ANSI!
+\c !endif
\c IntOp $2 $2 + 1
\c Goto loop
\c done:
\c FileClose $5
\c System::Free $1
\c System::Free $3
-\c Goto exit
-\c error:
-\c MessageBox MB_OK error
-\c exit:
-\c Pop $6
-\c Pop $4
-\c Pop $3
-\c Pop $2
-\c Pop $1
-\c Pop $0
-\c Exch $5
-\c FunctionEnd
-
-Here's the function to generate a UTF-16LE file if you're building a \R{intro-unicode}{Unicode installer}.
-
-\c !define LVM_GETITEMCOUNT 0x1004
-\c !define LVM_GETITEMTEXTW 0x1073
-\c
-\c Function DumpLog # Written by KiCHiK, modified by Jim Park
-\c Exch $5
-\c Push $0
-\c Push $1
-\c Push $2
-\c Push $3
-\c Push $4
-\c Push $6
-\c
-\c FindWindow $0 "#32770" "" $HWNDPARENT
-\c GetDlgItem $0 $0 1016
-\c StrCmp $0 0 error
-\c FileOpen $5 $5 "w"
-\c FileWriteWord $5 0xfeff ; Write the BOM
-\c StrCmp $5 0 error
-\c SendMessage $0 ${LVM_GETITEMCOUNT} 0 0 $6
-\c System::StrAlloc ${NSIS_MAX_STRLEN}
-\c Pop $3
-\c StrCpy $2 0
-\c System::Call "*(i, i, i, i, i, i, i, i, i) p \
-\c (0, 0, 0, 0, 0, r3, ${NSIS_MAX_STRLEN}) .r1"
-\c loop: StrCmp $2 $6 done
-\c System::Call "User32::SendMessageW(p, i, p, p) i \
-\c ($0, ${LVM_GETITEMTEXTW}, $2, r1)"
-\c System::Call "*$3(&t${NSIS_MAX_STRLEN} .r4)"
-\c FileWriteUTF16LE $5 "$4$\r$\n"
-\c IntOp $2 $2 + 1
-\c Goto loop
-\c done:
-\c FileClose $5
-\c System::Free $1
-\c System::Free $3
-\c Goto exit
-\c error:
-\c MessageBox MB_OK error
\c exit:
\c Pop $6
\c Pop $4
@@ -314,8 +266,7 @@ Here's the function to generate a UTF-16LE file if you're building a \R{intro-un
\H{readreg_multi_sz} How to Read REG_MULTI_SZ Values
-KiCHiK wrote this script to help rpetges in \W{http://forums.winamp.com/showthread.php?s=&threadid=131154}{this forum thread}. It reads a registry value of the type REG_MULTI_SZ and prints it out. Don't forget to edit where it says "Edit this!" when you test this script. The values must point to a REG_MULTI_SZ value or the example will spit out an error.
-
+\#{KiCHiK wrote this script to help rpetges in \W{http://forums.winamp.com/showthread.php?s=&threadid=131154}{this forum thread}.} This example reads a registry value of the type REG_MULTI_SZ and prints it out. Don't forget to edit where it says "Edit this!" when you test this script. The values must point to a REG_MULTI_SZ value or the example will spit out an error.
\c OutFile "REG_MULTI_SZ Reader.exe"
\c Name "REG_MULTI_SZ Reader"
@@ -342,25 +293,24 @@ KiCHiK wrote this script to help rpetges in \W{http://forums.winamp.com/showthre
\c !define REG_LINK 6
\c !define REG_MULTI_SZ 7
\c
-\c !define RegOpenKeyEx "Advapi32::RegOpenKeyExA(i, t, i, i, *i) i"
-\c !define RegQueryValueEx "Advapi32::RegQueryValueExA(i, t, i, *i, i, *i) i"
-\c !define RegCloseKey "Advapi32::RegCloseKeyA(i) i"
+\c !define RegOpenKeyEx "Advapi32::RegOpenKeyEx(p, t, i, i, *p) i"
+\c !define RegQueryValueEx "Advapi32::RegQueryValueEx(p, t, p, *i, p, *i) i"
+\c !define RegCloseKey "Advapi32::RegCloseKeyA(p) i"
\c
\c ####### Edit this!
\c
-\c !define ROOT_KEY ${HKEY_CURRENT_USER}
-\c !define SUB_KEY "Software\Joe Software"
-\c !define VALUE "Strings"
+\c !define ROOT_KEY ${HKEY_LOCAL_MACHINE}
+\c !define SUB_KEY "SYSTEM\CurrentControlSet\Control\Lsa"
+\c !define VALUE "Security Packages"
\c
\c ####### Stop editing
\c
\c Section "Read"
-\c StrCpy $0 ""
\c StrCpy $1 ""
\c StrCpy $2 ""
\c StrCpy $3 ""
\c System::Call "${RegOpenKeyEx}(${ROOT_KEY}, '${SUB_KEY}', \
-\c 0, ${KEY_QUERY_VALUE}|${KEY_ENUMERATE_SUB_KEYS}, .r0) .r3"
+\c 0, ${KEY_QUERY_VALUE}|${KEY_ENUMERATE_SUB_KEYS}, 0 r0) .r3"
\c
\c StrCmp $3 0 goon
\c MessageBox MB_OK|MB_ICONSTOP "Can't open registry key! ($3)"
@@ -376,7 +326,7 @@ KiCHiK wrote this script to help rpetges in \W{http://forums.winamp.com/showthre
\c read:
\c
\c StrCmp $1 ${REG_MULTI_SZ} multisz
-\c MessageBox MB_OK|MB_ICONSTOP "Registry value no REG_MULTI_SZ! ($3)"
+\c MessageBox MB_OK|MB_ICONSTOP "Registry value not a REG_MULTI_SZ! ($3)"
\c Goto done
\c
\c multisz:
@@ -412,8 +362,11 @@ KiCHiK wrote this script to help rpetges in \W{http://forums.winamp.com/showthre
\c StrCmp $3 "" done
\c DetailPrint $3
\c StrLen $5 $3
-\c IntOp $4 $4 + $5
-\c IntOp $4 $4 + 1
+\c !if "${NSIS_CHAR_SIZE}" > 1
+\c IntOp $5 $5 * ${NSIS_CHAR_SIZE}
+\c !endif
+\c IntPtrOp $4 $4 + $5
+\c IntPtrOp $4 $4 + ${NSIS_CHAR_SIZE}
\c Goto loop
\c
\c done:
@@ -429,4 +382,4 @@ KiCHiK wrote this script to help rpetges in \W{http://forums.winamp.com/showthre
\H{unicode_defines}Predefined Macros for Unicode support
-There are two macros that can help you write scripts that work for both Unicode and ANSI installers. To figure out if the script is being compiled to generate a Unicode installer, use !ifdef to check for $\{NSIS_UNICODE\}. To see what the size of a character is, use $\{NSIS_CHAR_SIZE\}. It will be 1 for ANSI and 2 for Unicode installers.
+There are two macros that can help you write scripts that work for both Unicode and ANSI installers. To figure out if the script is being compiled to generate a Unicode installer, use !ifdef to check for NSIS_UNICODE. To see what the size of a character is, use $\{NSIS_CHAR_SIZE\}. It will be 1 for ANSI and 2 for Unicode installers.