B. Useful Functions

B. Useful Functions

Browsing

Home: NSIS User Manual

Previous chapter:
Next chapter:
B. Useful Functions

1 Get parent directory
2 Trim newlines
3 Get command-line parameters
4 Search in a string
5 Get Windows version
6 Get Internet Explorer version
7 Is .NET Framework installed?
8 Is Flash Player installed?
9 Add a shared DLL
10 Remove a shared DLL
11 Upgrade a DLL (macro)
12 Connect to the internet
13 More
Chapters

0. Table of Contents
1. Introduction to NSIS
2. Tutorial: The Basics
3. MakeNSIS Usage
4. Scripting Reference
B. Useful Functions
Index
NSIS

Home page:NSIS

Documentation:User Manual
Modern UI
InstallOptions2

1 Get parent directory

; 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

2 Trim newlines

; 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

3 Get command-line parameters

; 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

4 Search in a string

; 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

5 Get Windows version

; 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

6 Get Internet Explorer version

; 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

7 Is .NET Framework installed?

; 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

8 Is Flash Player installed?

; 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

9 Add a shared DLL

; 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

10 Remove a shared DLL

; 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

11 Upgrade a DLL (macro)

; 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

12 Connect to the internet

; 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

13 More

You can find more useful functions at the NSIS Archive, the NSIS forum and NSIS development page.


This page has been generated by
Scribe.
Last update Sat Apr 19 15:03:08 BST 2003