Précédent | Accueil | Suivant

Appendice B: Fonctions utiles

B.1 Obtenir le répertoire parent

 ; GetParent
 ; entrée, haut de la pile  (ex. C:\Program Files\Poop)
 ; sortie, haut de la pile (remplacement, par ex. C:\Program Files)
 ; ne modifie aucune autre variable.
 ;
 ; Usage:
 ;   Push "C:\Program Files\Repertoire\NimporteQuoi"
 ;   Call GetParent
 ;   Pop $R0
 ;   ; à ce point $R0 vaut "C:\Program Files\Repertoire"

 Function GetParent
 
   Exch $R0
   Push $R1
   Push $R2
   Push $R3
   
   StrCpy $R1 0
   StrLen $R2 $R0
   
   loop:
     IntOp $R1 $R1 + 1
     IntCmp $R1 $R2 get 0 get
     StrCpy $R3 $R0 1 -$R1
     StrCmp $R3 "\" get
     Goto loop
   
   get:
     StrCpy $R0 $R0 -$R1
     
     Pop $R3
     Pop $R2
     Pop $R1
     Exch $R0
     
 FunctionEnd

B.2 Enlever les nouvelles lignes

 ; TrimNewlines
 ; entrée, haut de la pile  (ex. nimportequoi$\r$\n)
 ; sortie, haut de la pile (remplacement, avec ex. toutca)
 ; ne modifit aucune autre variable.

 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

B.3 Obtenir les paramètres utilisés

 ; GetParameters
 ; entrée, aucune
 ; sortie, haut de la pile (remplacement, avec ex. toutca)
 ; ne modifie aucune autre variable.

 Function GetParameters
 
   Push $R0
   Push $R1
   Push $R2
   Push $R3
   
   StrCpy $R2 1
   StrLen $R3 $CMDLINE
   
   ;Check for quote or space
   StrCpy $R0 $CMDLINE $R2
   StrCmp $R0 '"' 0 +3
     StrCpy $R1 '"'
     Goto loop
   StrCpy $R1 " "
   
   loop:
     IntOp $R2 $R2 + 1
     StrCpy $R0 $CMDLINE 1 $R2
     StrCmp $R0 $R1 get
     StrCmp $R2 $R3 get
     Goto loop
   
   get:
     IntOp $R2 $R2 + 1
     StrCpy $R0 $CMDLINE 1 $R2
     StrCmp $R0 " " get
     StrCpy $R0 $CMDLINE "" $R2
   
   Pop $R3
   Pop $R2
   Pop $R1
   Exch $R0
 
 FunctionEnd

B.4 Rechercher dans une chaîne

 ; StrStr
 ; entrée, haut de la pile = chaine a rechercher
 ;         haut de la pile-1 = chaine dans laquelle chercher
 ; sortie, haut de la pile (remplacement avec la portion de la chaine restante)
 ; ne modifie aucune autre variable.
 ;
 ; Usage:
 ;   Push "c'est une putain de longue chaine"
 ;   Push "putain"
 ;   Call StrStr
 ;   Pop $R0
 ;  ($R0 at this point is "putain de longue chaine")

 Function StrStr
 Exch $R1 ; st=tete,vieux$R1, $R1=pointeur
   Exch   ; st=vieux$R1,tete
   Exch $R2 ; st=vieux$R1,vieux$R2, $R2=tete
   Push $R3
   Push $R4
   Push $R5
   StrLen $R3 $R1
   StrCpy $R4 0
   ; $R1=pointeur
   ; $R2=tete
   ; $R3=taille(pointeur)
   ; $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

B.5 Obtenir la version de Windows

 ; GetWindowsVersion
 ;
 ; Basée sur la fonction de Yazno, http://yazno.tripod.com/powerpimpit/
 ; Mise à jour par Joost Verburg
 ;
 ; Retour en haut de la pile
 ;
 ; Version de Windows (95, 98, ME, NT x.x, 2000, XP, 2003)
 ; ou
 ; '' (Version inconnue)
 ;
 ; Usage:
 ;   Call GetWindowsVersion
 ;   Pop $R0
 ;   ; a ce pointe $R0 est "NT 4.0" ou autre...
 
 Function GetWindowsVersion
 
   Push $R0
   Push $R1
 
   ReadRegStr $R0 HKLM \
   "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion

   IfErrors 0 lbl_winnt
   
   ; on est pas sous 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

B.6 Obtenir la version d'Internet Explorer

 ; GetIEVersion
 ;
 ; Basée sur la fonction de Yazno, http://yazno.tripod.com/powerpimpit/
 ; Retour en haut de la pile
 ; 1-6 (Version de IE installée)
 ; ou
 ; '' (IE n'est pas installé)
 ;
 ; Usage:
 ;   Call GetIEVersion
 ;   Pop $R0
 ;   ; à ce point $R0 vaut "5" ou autre...

 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: ; version d'ie plus ancienne
     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' ; par défaut à ie3 si différent de 100, 101, ou 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

B.7 Le Framework .NET est-il installé ?

 ; 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"
   # supprime le back slash de fin
   Push $4
   Exch $EXEDIR
   Exch $EXEDIR
   Pop $4
   # si le répertoire racine n'existe pas, .NET n'est pas installé
   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

B.8 Le lecteur Macromedia Flash est-il installé ?

 ; IsFlashInstalled
 ;
 ; Par Yazno, http://yazno.tripod.com/powerpimpit/
 ; Retour en haut de la pile
 ; 0 (Flash n'est pas installé)
 ; ou
 ; 1 (Flash est installé)
 ;
 ; Usage:
 ;   Call IsFlashInstalled
 ;   Pop $R0
 ;   ; $R0 vaut à ce point "1" ou "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

B.9 Ajouter une bibliothèque partagée

 ; AddSharedDLL
 ;
 ; Incrémente un compteur de DLLs partagées.
 ; Utilisez en ne passant qu'un élément dans la pile (le chemin complet de la 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

B.10 Enlever une bibliothèque partagée

 ; un.RemoveSharedDLL
 ;
 ; Décrémente un compteur de DLLs partagées, et l'enleve si nécessaire.
 ; Utilisez en passant un élement dans la pile (le chemin complet de la DLL).
 ; Note: pour utiliser dans l'installation principale (et non la désinstallation), renommez la fonction
 ; en 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

B.11 Mettre à jour une DLL (macro)

Une copie de cette macro existe dans le dossier Include, vous 'navez donc qu'à inclure UpgradeDLL.nsh pour l'utiliser.

 ; Macro - Mettre à jour un fichier DLL
 ; Ecrit par Joost Verburg
 ; ------------------------
 ;
 ; Parametres :
 ; LOCALFILE   - Emplacement du nouveau fichier DLL (sur le système de compilation)
 ; DESTFILE    - Emplacement du fichier DLL devant être mis à jour (sur le système de l'utilisateur)
 ; TEMPBASEDIR - Répertoire, sur le système de l'utilisateur, de stockage du fichier temporaire, lorsque le système
 ;               doit redémarrer.
 ;               Pour le support Win9x, il doit être sur la même partition que DESTFILE!
 ;               Le répertoire temp de Windows peut être situé sur n'importe quelle partition : ainsi vous ne pouvez
 ;               pas utiliser ce répertoire.
 ;
 ; !define UPGRADEDLL_NOREGISTER si vous voulez mettre à jour une DLL qui ne peut pas être enregistrée
 ;
 ; Note : Si vous voulez supporter Win9x, vous ne pouvez utiliser que des noms de fichiers courts (8.3)
 ;
 ; Exemple d'utilisation :
 ; !insertmacro UpgradeDLL "nomdll.dll" "$SYSDIR\nomdll.dll" "$SYSDIR"
 ;

!macro UpgradeDLL LOCALFILE DESTFILE TEMPBASEDIR

  Push $R0
  Push $R1
  Push $R2
  Push $R3
  Push $R4
  Push $R5

  ;------------------------
  ;Unique number for labels

  !define UPGRADEDLL_UNIQUE ${__LINE__}

  ;------------------------
  ;Copy the parameters used on run-time to a variable
  ;This allows the usage of variables as paramter

  StrCpy $R4 "${DESTFILE}"
  StrCpy $R5 "${TEMPBASEDIR}"

  ;------------------------
  ;Check file and version

  IfFileExists $R4 0 upgradedll.copy_${UPGRADEDLL_UNIQUE}

  ClearErrors
    GetDLLVersionLocal "${LOCALFILE}" $R0 $R1
    GetDLLVersion $R4 $R2 $R3
  IfErrors upgradedll.upgrade_${UPGRADEDLL_UNIQUE}

  IntCmpU $R0 $R2 0 upgradedll.done_${UPGRADEDLL_UNIQUE} upgradedll.upgrade_${UPGRADEDLL_UNIQUE}
  IntCmpU $R1 $R3 upgradedll.done_${UPGRADEDLL_UNIQUE} upgradedll.done_${UPGRADEDLL_UNIQUE} \
    upgradedll.upgrade_${UPGRADEDLL_UNIQUE}

  ;------------------------
  ;Let's upgrade the DLL!

  SetOverwrite try

  upgradedll.upgrade_${UPGRADEDLL_UNIQUE}:
    !ifndef UPGRADEDLL_NOREGISTER
      ;Unregister the DLL
      UnRegDLL $R4
    !endif

  ;------------------------
  ;Try to copy the DLL directly

  ClearErrors
    StrCpy $R0 $R4
    Call :upgradedll.file_${UPGRADEDLL_UNIQUE}
  IfErrors 0 upgradedll.noreboot_${UPGRADEDLL_UNIQUE}

  ;------------------------
  ;DLL is in use. Copy it to a temp file and Rename it on reboot.

  GetTempFileName $R0 $R5
    Call :upgradedll.file_${UPGRADEDLL_UNIQUE}
  Rename /REBOOTOK $R0 $R4

  ;------------------------
  ;Register the DLL on reboot

  !ifndef UPGRADEDLL_NOREGISTER
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
      "Register $R4" 'rundll32.exe "$R4",DllRegisterServer'
  !endif

  Goto upgradedll.done_${UPGRADEDLL_UNIQUE}

  ;------------------------
  ;DLL does not exist - just extract

  upgradedll.copy_${UPGRADEDLL_UNIQUE}:
    StrCpy $R0 $R4
    Call :upgradedll.file_${UPGRADEDLL_UNIQUE}

  ;------------------------
  ;Register the DLL

  upgradedll.noreboot_${UPGRADEDLL_UNIQUE}:
    !ifndef UPGRADEDLL_NOREGISTER
      RegDLL $R4
    !endif

  ;------------------------
  ;Done

  upgradedll.done_${UPGRADEDLL_UNIQUE}:

  Pop $R5
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R1
  Pop $R0

  ;------------------------
  ;End

  Goto upgradedll.end_${UPGRADEDLL_UNIQUE}

  ;------------------------
  ;Called to extract the DLL

  upgradedll.file_${UPGRADEDLL_UNIQUE}:
    File /oname=$R0 "${LOCALFILE}"
    Return

  upgradedll.end_${UPGRADEDLL_UNIQUE}:

 ;------------------------
 ;Restore settings

 SetOverwrite lastused
 
 !undef UPGRADEDLL_UNIQUE

!macroend

B.12 Connexion à Internet

 ; ConnectInternet (utilise le plugin Dialer)
 ; Ecrit par Joost Verburg 
 ;
 ; ette fonction essaye de créer une connexion sur l'Internet s'il n'en existe
 ; pas déjà une. Si vous n'êtes pas certain qu'un système utilisant cette installation
 ; possèdera une connexion Internet active, appellez cette fonction avant de télécharger
 ; des fichiers en utilisant NSISdl.
 ; 
 ; Cette fonction requiert Internet Explorer 3, mais demande à se connecter manuellement si
 ; IE3 n'est pas installé
 
 Function ConnectInternet
 
   Push $R0
     
     ClearErrors
     Dialer::AttemptConnect
     IfErrors noie3
     
     Pop $R0
     StrCmp $R0 "online" connected
       MessageBox MB_OK|MB_ICONSTOP "Impossible de se connecter à Internet."
       Quit ;Enlevez cette ligne pour que cette erreur ne soit pas fatale
     
     noie3:
   
     ; IE3 non installée
     MessageBox MB_OK|MB_ICONINFORMATION "Veuillez maintenant vous connecter sur Internet."
     
     connected:
   
   Pop $R0
   
 FunctionEnd

B.13 Plus

Vous pouvez trouver d'autres fonctions utiles dans l'Archive NSIS, sur le forum NSIS et sur la NSIS page de développement.

Précédent | Accueil | Suivant