; GetParent
; input, top of stack (e.g. C:\Program Files\Poop)
; output, top of stack (replaces, with e.g. C:\Program Files)
; modifies no other variables.
;
; Usage:
; Push "C:\Program Files\Directory\Whatever"
; Call GetParent
; Pop $R0
; ; at this point $R0 will equal "C:\Program Files\Directory"
Function GetParent
Exch $R0 ; old $R0 is on top of stack
Push $R1
Push $R2
StrCpy $R1 -1
loop:
StrCpy $R2 $R0 1 $R1
StrCmp $R2 "" exit
StrCmp $R2 "\" exit
IntOp $R1 $R1 - 1
Goto loop
exit:
StrCpy $R0 $R0 $R1
Pop $R2
Pop $R1
Exch $R0 ; put $R0 on top of stack, restore $R0 to original value
FunctionEnd
; TrimNewlines ; input, top of stack (e.g. whatever$\r$\n) ; output, top of stack (replaces, with e.g. whatever) ; modifies no other variables. Function TrimNewlines Exch $R0 Push $R1 Push $R2 StrCpy $R1 0 loop: IntOp $R1 $R1 - 1 StrCpy $R2 $R0 1 $R1 StrCmp $R2 "$\r" loop StrCmp $R2 "$\n" loop IntOp $R1 $R1 + 1 IntCmp $R1 0 no_trim_needed StrCpy $R0 $R0 $R1 no_trim_needed: Pop $R2 Pop $R1 Exch $R0 FunctionEnd
; GetParameters
; input, none
; output, top of stack (replaces, with e.g. whatever)
; modifies no other variables.
Function GetParameters
Push $R0
Push $R1
Push $R2
StrCpy $R0 $CMDLINE 1
StrCpy $R1 '"'
StrCpy $R2 1
StrCmp $R0 '"' loop
StrCpy $R1 ' ' ; we're scanning for a space instead of a quote
loop:
StrCpy $R0 $CMDLINE 1 $R2
StrCmp $R0 $R1 loop2
StrCmp $R0 "" loop2
IntOp $R2 $R2 + 1
Goto loop
loop2:
IntOp $R2 $R2 + 1
StrCpy $R0 $CMDLINE 1 $R2
StrCmp $R0 " " loop2
StrCpy $R0 $CMDLINE "" $R2
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
; StrStr
; input, top of stack = string to search for
; top of stack-1 = string to search in
; output, top of stack (replaces with the portion of the string remaining)
; modifies no other variables.
;
; Usage:
; Push "this is a long ass string"
; Push "ass"
; Call StrStr
; Pop $R0
; ($R0 at this point is "ass string")
Function StrStr
Exch $R1 ; st=haystack,old$R1, $R1=needle
Exch ; st=old$R1,haystack
Exch $R2 ; st=old$R1,old$R2, $R2=haystack
Push $R3
Push $R4
Push $R5
StrLen $R3 $R1
StrCpy $R4 0
; $R1=needle
; $R2=haystack
; $R3=len(needle)
; $R4=cnt
; $R5=tmp
loop:
StrCpy $R5 $R2 $R3 $R4
StrCmp $R5 $R1 done
StrCmp $R5 "" done
IntOp $R4 $R4 + 1
Goto loop
done:
StrCpy $R1 $R2 "" $R4
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Exch $R1
FunctionEnd
; GetWindowsVersion
;
; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/
; Updated by Joost Verburg
;
; Returns on top of stack
;
; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003)
; or
; '' (Unknown Windows Version)
;
; Usage:
; Call GetWindowsVersion
; Pop $R0
; ; at this point $R0 is "NT 4.0" or whatnot
Function GetWindowsVersion
Push $R0
Push $R1
ReadRegStr $R0 HKLM \
"SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
IfErrors 0 lbl_winnt
; we are not NT
ReadRegStr $R0 HKLM \
"SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber
StrCpy $R1 $R0 1
StrCmp $R1 '4' 0 lbl_error
StrCpy $R1 $R0 3
StrCmp $R1 '4.0' lbl_win32_95
StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98
lbl_win32_95:
StrCpy $R0 '95'
Goto lbl_done
lbl_win32_98:
StrCpy $R0 '98'
Goto lbl_done
lbl_win32_ME:
StrCpy $R0 'ME'
Goto lbl_done
lbl_winnt:
StrCpy $R1 $R0 1
StrCmp $R1 '3' lbl_winnt_x
StrCmp $R1 '4' lbl_winnt_x
StrCpy $R1 $R0 3
StrCmp $R1 '5.0' lbl_winnt_2000
StrCmp $R1 '5.1' lbl_winnt_XP
StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error
lbl_winnt_x:
StrCpy $R0 "NT $R0" 6
Goto lbl_done
lbl_winnt_2000:
Strcpy $R0 '2000'
Goto lbl_done
lbl_winnt_XP:
Strcpy $R0 'XP'
Goto lbl_done
lbl_winnt_2003:
Strcpy $R0 '2003'
Goto lbl_done
lbl_error:
Strcpy $R0 ''
lbl_done:
Pop $R1
Exch $R0
FunctionEnd
; GetIEVersion
;
; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/
; Returns on top of stack
; 1-6 (Installed IE Version)
; or
; '' (IE is not installed)
;
; Usage:
; Call GetIEVersion
; Pop $R0
; ; at this point $R0 is "5" or whatnot
Function GetIEVersion
Push $R0
ClearErrors
ReadRegStr $R0 HKLM "Software\Microsoft\Internet Explorer" "Version"
IfErrors lbl_123 lbl_456
lbl_456: ; ie 4+
Strcpy $R0 $R0 1
Goto lbl_done
lbl_123: ; older ie version
ClearErrors
ReadRegStr $R0 HKLM "Software\Microsoft\Internet Explorer" "IVer"
IfErrors lbl_error
StrCpy $R0 $R0 3
StrCmp $R0 '100' lbl_ie1
StrCmp $R0 '101' lbl_ie2
StrCmp $R0 '102' lbl_ie2
StrCpy $R0 '3' ; default to ie3 if not 100, 101, or 102.
Goto lbl_done
lbl_ie1:
StrCpy $R0 '1'
Goto lbl_done
lbl_ie2:
StrCpy $R0 '2'
Goto lbl_done
lbl_error:
StrCpy $R0 ''
lbl_done:
Exch $R0
FunctionEnd
; IsDotNETInstalled
;
; Usage:
; Call IsDotNETInstalled
; Pop $0
; StrCmp $0 1 found.NETFramework no.NETFramework
Function IsDotNETInstalled
Push $0
Push $1
Push $2
Push $3
Push $4
ReadRegStr $4 HKEY_LOCAL_MACHINE \
"Software\Microsoft\.NETFramework" "InstallRoot"
# remove trailing back slash
Push $4
Exch $EXEDIR
Exch $EXEDIR
Pop $4
# if the root directory doesn't exist .NET is not installed
IfFileExists $4 0 noDotNET
StrCpy $0 0
EnumStart:
EnumRegKey $2 HKEY_LOCAL_MACHINE \
"Software\Microsoft\.NETFramework\Policy" $0
IntOp $0 $0 + 1
StrCmp $2 "" noDotNET
StrCpy $1 0
EnumPolicy:
EnumRegValue $3 HKEY_LOCAL_MACHINE \
"Software\Microsoft\.NETFramework\Policy\$2" $1
IntOp $1 $1 + 1
StrCmp $3 "" EnumStart
IfFileExists "$4\$2.$3" foundDotNET EnumPolicy
noDotNET:
StrCpy $0 0
Goto done
foundDotNET:
StrCpy $0 1
done:
Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd
; IsFlashInstalled
;
; By Yazno, http://yazno.tripod.com/powerpimpit/
; Returns on top of stack
; 0 (Flash is not installed)
; or
; 1 (Flash is installed)
;
; Usage:
; Call IsFlashInstalled
; Pop $R0
; ; $R0 at this point is "1" or "0"
Function IsFlashInstalled
Push $R0
ClearErrors
ReadRegStr $R0 HKCR "CLSID\{D27CDB6E-AE6D-11cf-96B8-444553540000}" ""
IfErrors lbl_na
StrCpy $R0 1
Goto lbl_end
lbl_na:
StrCpy $R0 0
lbl_end:
Exch $R0
FunctionEnd
; AddSharedDLL ; ; Increments a shared DLLs reference count. ; Use by passing one item on the stack (the full path of the DLL). ; ; Usage: ; Push $SYSDIR\myDll.dll ; Call AddSharedDLL ; Function AddSharedDLL Exch $R1 Push $R0 ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 IntOp $R0 $R0 + 1 WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 $R0 Pop $R0 Pop $R1 FunctionEnd
; un.RemoveSharedDLL
;
; Decrements a shared DLLs reference count, and removes if necessary.
; Use by passing one item on the stack (the full path of the DLL).
; Note: for use in the main installer (not the uninstaller), rename the
; function to RemoveSharedDLL.
;
; Usage:
; Push $SYSDIR\myDll.dll
; Call un.RemoveSharedDLL
;
Function un.RemoveSharedDLL
Exch $R1
Push $R0
ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1
StrCmp $R0 "" remove
IntOp $R0 $R0 - 1
IntCmp $R0 0 rk rk uk
rk:
DeleteRegValue HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1
goto Remove
uk:
WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 $R0
Goto noremove
remove:
Delete /REBOOTOK $R1
noremove:
Pop $R0
Pop $R1
FunctionEnd
; Macro - Upgrade DLL File
; Written by Joost Verburg
; ------------------------
;
; Example of usage:
; !insertmacro UpgradeDLL "dllname.dll" "$SYSDIR\dllname.dll"
;
; !define UPGRADEDLL_NOREGISTER if you want to upgrade a DLL which cannot be registered
;
; Note that this macro sets overwrite to ON (the default) when it has been inserted.
; If you are using another setting, set it again after inserting the macro.
!macro UpgradeDLL LOCALFILE DESTFILE
Push $R0
Push $R1
Push $R2
Push $R3
;------------------------
;Check file and version
IfFileExists "${DESTFILE}" "" "copy_${LOCALFILE}"
ClearErrors
GetDLLVersionLocal "${LOCALFILE}" $R0 $R1
GetDLLVersion "${DESTFILE}" $R2 $R3
IfErrors "upgrade_${LOCALFILE}"
IntCmpU $R0 $R2 "" "done_${LOCALFILE}" "upgrade_${LOCALFILE}"
IntCmpU $R1 $R3 "done_${LOCALFILE}" "done_${LOCALFILE}" "upgrade_${LOCALFILE}"
;------------------------
;Let's upgrade the DLL!
SetOverwrite try
"upgrade_${LOCALFILE}:"
!ifndef UPGRADEDLL_NOREGISTER
;Unregister the DLL
UnRegDLL "${DESTFILE}"
!endif
;------------------------
;Try to copy the DLL directly
ClearErrors
StrCpy $R0 "${DESTFILE}"
Call ":file_${LOCALFILE}"
IfErrors "" "noreboot_${LOCALFILE}"
;------------------------
;DLL is in use. Copy it to a temp file and Rename it on reboot.
GetTempFileName $R0
Call ":file_${LOCALFILE}"
Rename /REBOOTOK $R0 "${DESTFILE}"
;------------------------
;Register the DLL on reboot
!ifndef UPGRADEDLL_NOREGISTER
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
"Register ${DESTFILE}" '"$SYSDIR\rundll32.exe" "${DESTFILE},DllRegisterServer"'
!endif
Goto "done_${LOCALFILE}"
;------------------------
;DLL does not exist - just extract
"copy_${LOCALFILE}:"
StrCpy $R0 "${DESTFILE}"
Call ":file_${LOCALFILE}"
;------------------------
;Register the DLL
"noreboot_${LOCALFILE}:"
!ifndef UPGRADEDLL_NOREGISTER
RegDLL "${DESTFILE}"
!endif
;------------------------
;Done
"done_${LOCALFILE}:"
Pop $R3
Pop $R2
Pop $R1
Pop $R0
;------------------------
;End
Goto "end_${LOCALFILE}"
;------------------------
;Called to extract the DLL
"file_${LOCALFILE}:"
File /oname=$R0 "${LOCALFILE}"
Return
"end_${LOCALFILE}:"
;------------------------
;Set overwrite to default
;(was set to TRY above)
SetOverwrite on
!macroend
; ConnectInternet (uses Dialer plugin)
; Written by Joost Verburg
;
; This function attempts to make a connection to the internet if there is no
; connection available. If you are not sure that a system using the installer
; has an active internet connection, call this function before downloading
; files with NSISdl.
;
; The function requires Internet Explorer 3, but asks to connect manually if
; IE3 is not installed.
Function ConnectInternet
Push $R0
ClearErrors
Dialer::AttemptConnect
IfErrors noie3
Pop $R0
StrCmp $R0 "online" connected
MessageBox MB_OK|MB_ICONSTOP "Cannot connect to the internet."
Quit ;Remove to make error not fatal
noie3:
; IE3 not installed
MessageBox MB_OK|MB_ICONINFORMATION "Please connect to the internet now."
connected:
Pop $R0
FunctionEnd
You can find more useful functions at the NSIS Archive, the NSIS forum and NSIS development page.