LilyPond
From NSIS Wiki
Jump to navigationJump to search
Description
GNU LilyPond is a music typesetter: it produces music scores through TeX and Guile scripting
The Script
http://github.com/janneke/gub/tree/master/nsis/
It doesn't force people to accept the license for mere use (as it's the GNU GPL) and cleanly separate pre- and post-install actions (mainly integration with Windows Explorer). It installs several sub-components, namely Guile and Python. Files are selected from uninstallation based on the install log rather than hard-coded rules (cf. Uninstall_only_installed_files).
- lilypond.nsi:
;;;; lilypond.nsi -- LilyPond installer script for Microsoft Windows ;;;; (c) 2005--2007 ;;;; Jan Nieuwenhuizen <janneke@gnu.org> ;;;; Han-Wen Nienhuys <janneke@gnu.org> ;;;; licence: GNU GPL ;; For quick [wine] test runs ;; !define TEST "1" ;;; substitutions !define ENVIRON "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" !define UNINSTALL \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRETTY_NAME}" !define USER_SHELL_FOLDERS \ "Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" Var "EDITOR" Var "UP_DESKTOP" !define UninstLog "files.txt" Var UninstLog ; Uninstall log file missing. LangString UninstLogMissing ${LANG_ENGLISH} "${UninstLog} not found.$\r$\nCannot uninstall." !include "substitute.nsh" ${StrLoc} ${UnStrLoc} ;;SetCompressor lzma ; very slow ;;SetCompressor zlib SetCompressor bzip2 ;; Name "${PRETTY_NAME}" Caption "${PRETTY_NAME} ${INSTALLER_VERSION} for Microsoft Windows" BrandingText "${PRETTY_NAME} installer v1.0" InstallDir $PROGRAMFILES\${PRETTY_NAME} InstallDirRegKey HKLM "Software\${PRETTY_NAME}" "Install_Dir" CRCCheck on XPStyle on InstallColors /windows BGGradient 000000 E8FFE8 FFFFFF ;; Use Finish iso Close for the [close button text] ;; Although nothing happens after Close, experienced Windows users feel ;; much more with "Finish" than with Close. MiscButtonText Back Next Cancel Finish LicenseText "Conditions for redistributing ${PRETTY_NAME}" "Next" LicenseData "${ROOT}\license\${NAME}" LicenseForceSelection off Page license ;; FIXME: the intstaller will crash on File /r commands if Page ;; directory is not used. Page directory Page components Page instfiles UninstPage uninstConfirm UninstPage instfiles Section "${PRETTY_NAME} (required)" ;; In silent mode (invoke as: setup.exe /S), generate an install log. ifSilent 0 silent Logset on silent: IfFileExists $INSTDIR\usr\bin\${CANARY_EXE}.exe no_overwrite_error fresh_install no_overwrite_error: MessageBox MB_OK "Previous version of ${PRETTY_NAME} found$\r$\nUninstall the old version first." Abort "Previous version of ${PRETTY_NAME} found$\r$\nUninstall the old version first." fresh_install: SetOverwrite on AllowSkipFiles on SetOutPath $INSTDIR File /r "${ROOT}\usr" File /r "${ROOT}\license" File /r "${ROOT}\files.txt" WriteUninstaller "uninstall.exe" CreateDirectory "$INSTDIR\usr\bin" Call registry_installer ;; Use tested lilypad for now StrCpy $EDITOR "$INSTDIR\usr\bin\lilypad.exe" ;; FIXME: what is UP_DESKTOP used for? Call find_desktop Call registry_guile Call registry_lilypond ;; FIXME: these postinstall things should be part of their ;; respective packages once we have min-apt or Cygwin's ;; setup.exe in place. Call postinstall_lilypond Call postinstall_lilypad SectionEnd ;; Optional section (can be disabled by the user) Section "Bundled Python" ;; Only make bundled python interpreter the default ;; if user wants it to be (i.e. for the average windows ;; user who only cares that software works just like that) Call registry_python SectionEnd ;; Optional section (can be disabled by the user) Section "Start Menu Shortcuts" ;; First install for all users, if anything fails, install ;; for current user only. ClearErrors ;; The OutPath specifies the CWD of the command. For desktop ;; shortcuts, set to a string that expands to the desktop folder ;; of the user who runs LilyPond. ReadRegStr $R0 HKCU "${USER_SHELL_FOLDERS}" "Desktop" SetOutPath '"$R0"' SetShellVarContext all ;; Working directory: %USERPROFILE%\<locale's-desktop-folder-name>, ;; but that string is not expanded. ;; Let's see what happens when outputting to the shared desktop. SetOutPath "$DESKTOP" Call create_shortcuts ;; That also did not work, often the other users do no write access ;; there. ;; If no write access for all, delete common stuff and opt for ;; install for current user only. IfErrors 0 exit Delete "$DESKTOP\LilyPond.lnk" Delete "$SMPROGRAMS\LilyPond\*.*" RMDir "$SMPROGRAMS\LilyPond" ;; $DESKTOP should expand to the same location as the outpath above, ;; but nsis may handle anomalies better. current_user: SetShellVarContext current SetOutPath "$DESKTOP" Call create_shortcuts exit: SetShellVarContext current SetOutPath $INSTDIR SectionEnd ;; copy & paste from the NSIS code examples Function un.install_installed_files IfFileExists "$INSTDIR\${UninstLog}" +3 MessageBox MB_OK|MB_ICONSTOP "$(UninstLogMissing)" Abort Push $R0 Push $R1 Push $R2 SetFileAttributes "$INSTDIR\${UninstLog}" NORMAL FileOpen $UninstLog "$INSTDIR\${UninstLog}" r StrCpy $R1 0 GetLineCount: ClearErrors FileRead $UninstLog $R0 IntOp $R1 $R1 + 1 IfErrors 0 GetLineCount LoopRead: FileSeek $UninstLog 0 SET StrCpy $R2 0 FindLine: FileRead $UninstLog $R0 IntOp $R2 $R2 + 1 StrCmp $R1 $R2 0 FindLine StrCpy $R0 "$INSTDIR\$R0" -2 IfFileExists "$R0\*.*" 0 +3 RMDir $R0 #is dir Goto +3 IfFileExists "$R0" 0 +2 Delete "$R0" #is file IntOp $R1 $R1 - 1 StrCmp $R1 0 LoopDone Goto LoopRead LoopDone: FileClose $UninstLog Pop $R2 Pop $R1 Pop $R0 FunctionEnd ;; end copy & paste Section "Uninstall" ifSilent 0 silent Logset on silent: DeleteRegKey HKLM SOFTWARE\${PRETTY_NAME} DeleteRegKey HKLM "Applications\lilypond-windows.exe" DeleteRegKey HKLM "${UNINSTALL}" DeleteRegKey HKCR ".ly" DeleteRegKey HKCR "ly_auto_file" DeleteRegKey HKCR "${PRETTY_NAME}\shell\open\command" "" DeleteRegKey HKCR "${PRETTY_NAME}\shell\generate\command" "" DeleteRegKey HKCR "${PRETTY_NAME}\DefaultIcon" "" DeleteRegKey HKCR "${PRETTY_NAME}" "" DeleteRegKey HKCR "textedit" "" DeleteRegKey HKCR ".scm" DeleteRegKey HKCR "GUILE\shell\open\command" "" DeleteRegKey HKCR "GUILE" "" DeleteRegKey HKCU "Applications\lilypond-windows.exe" DeleteRegKey HKCU ".ly" ReadRegStr $R0 HKLM "${ENVIRON}" "PATH" ${UnStrLoc} $0 $R0 "$INSTDIR\usr\bin;" > path_loop: StrCmp $0 "" path_done StrLen $1 "$INSTDIR\usr\bin;" IntOp $2 $0 + $1 StrCpy $3 $R0 $0 0 StrCpy $4 $R0 10000 $2 WriteRegExpandStr HKLM "${ENVIRON}" "PATH" "$3$4" ReadRegStr $R0 HKLM "${ENVIRON}" "PATH" ${UnStrLoc} $0 $R0 "$INSTDIR\usr\bin;" > StrCmp $0 "" path_done path_loop path_done: ;; Remove files and uninstaller ;; Try only to delete ${PRETTY_NAME} (and not user) stuff Delete "$INSTDIR\usr\bin\variables.sh.in" Delete "$INSTDIR\usr\bin\variables.sh" Delete "$INSTDIR\usr\bin\lilypond-windows.bat.in" call un.install_installed_files ;; Remove shortcuts, if any SetShellVarContext all Delete "$SMPROGRAMS\${PRETTY_NAME}\*.*" Delete "$DESKTOP\${PRETTY_NAME}.lnk" RMDir "$SMPROGRAMS\${PRETTY_NAME}" SetShellVarContext current Delete "$SMPROGRAMS\${PRETTY_NAME}\*.*" Delete "$DESKTOP\${PRETTY_NAME}.lnk" RMDir "$SMPROGRAMS\${PRETTY_NAME}" ;; Remove directories used RMDir "$SMPROGRAMS\${PRETTY_NAME}" RMDir "$INSTDIR\usr\bin" RMDir "$INSTDIR\usr\" Delete "$INSTDIR\uninstall.exe" Delete "$INSTDIR\files.txt" RMDir "$INSTDIR" SectionEnd Function registry_installer WriteRegStr HKLM "SOFTWARE\${PRETTY_NAME}" "Install_Dir" "$INSTDIR" WriteRegStr HKLM "${UNINSTALL}" "DisplayName" "${PRETTY_NAME}" WriteRegStr HKLM "${UNINSTALL}" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegDWORD HKLM "${UNINSTALL}" "NoModify" 1 WriteRegDWORD HKLM "${UNINSTALL}" "NoRepair" 1 FunctionEnd !include "lilypond-prepost.nsh" Function find_desktop ReadRegStr $R0 HKCU "${USER_SHELL_FOLDERS}" "Desktop" StrCpy $UP_DESKTOP "$R0" StrCmp $UP_DESKTOP "" 0 exit StrCpy $UP_DESKTOP "%USERPROFILE%\Desktop" exit: FunctionEnd
- lilypond-prepost.nsh:
Function create_shortcuts ;; Start menu CreateDirectory "$SMPROGRAMS\LilyPond" CreateShortCut "$SMPROGRAMS\LilyPond\LilyPond.lnk" \ "$INSTDIR\usr\bin\lilypond-windows.exe" "-dgui" \ "$INSTDIR\usr\bin\lilypond-windows.exe" 0 SW_SHOWMINIMIZED CreateShortCut "$SMPROGRAMS\LilyPond\LilyPond Tutorial.lnk" \ "http://lilypond.org/tutorial" "" \ "firefox.exe" 0 CreateShortCut "$SMPROGRAMS\LilyPond\LilyPond Website.lnk" \ "http://lilypond.org/" "" \ "firefox.exe" 0 CreateShortCut "$SMPROGRAMS\LilyPond\Music in Mutopia.lnk" \ "http://www.mutopiaproject.org" "" \ "$INSTDIR\usr\bin\lilypond-windows.exe" 1 CreateShortCut "$SMPROGRAMS\LilyPond\Examples.lnk" \ "$INSTDIR\usr\share\doc\lilypond-${INSTALLER_VERSION}-${INSTALLER_BUILD}\input" "" \ "$INSTDIR\usr\bin\lilypond-windows.exe" 1 CreateShortCut "$SMPROGRAMS\LilyPond\Uninstall.lnk" \ "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 ;; Desktop ClearErrors ReadRegStr $R0 HKLM \ "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion IfErrors dos windows dos: CreateShortCut "$DESKTOP\LilyPond.lnk" "" \ "$INSTDIR\usr\bin\lilypond-windows.bat" \ "$INSTDIR\usr\bin\lilypond-windows.exe" 0 SW_SHOWMINIMIZED Goto exit windows: CreateShortCut "$DESKTOP\LilyPond.lnk" \ "$INSTDIR\usr\bin\lilypond-windows.exe" "-dgui" \ "$INSTDIR\usr\bin\lilypond-windows.exe" 0 SW_SHOWMINIMIZED exit: FunctionEnd Function registry_lilypond ReadRegStr $R0 HKLM "${ENVIRON}" "PATH" WriteRegExpandStr HKLM "${ENVIRON}" "PATH" "$R0;$INSTDIR\usr\bin" WriteRegStr HKCR ".ly" "" "LilyPond" WriteRegStr HKCR ".ly" "LilyPond" "LilyPond" WriteRegStr HKCR ".ly" "Content Type" "text/lilypond-source" ;;ly_icon: WriteRegStr HKCR "LilyPond" "DefaultIcon" "" WriteRegStr HKCR "LilyPond\DefaultIcon" "" \ "$INSTDIR\usr\bin\lilypond-windows.exe,1" ;;ly_open: ReadRegStr $R0 HKCR "LilyPond\shell\open\command" "" ;;StrCmp $R0 "" 0 ly_edit WriteRegStr HKCR "LilyPond\shell" "" "open" WriteRegExpandStr HKCR "LilyPond\shell\open\command" "" '"$EDITOR" "%1"' ;;ly_edit: ReadRegStr $R0 HKCR "LilyPond\shell\edit\command" "" ;;StrCmp $R0 "" 0 ly_generate WriteRegStr HKCR "LilyPond\shell" "" "edit" WriteRegStr HKCR "LilyPond\shell\edit" "" "&Edit source..." WriteRegExpandStr HKCR "LilyPond\shell\edit\command" "" '"$EDITOR" "%1"' ;;ly_generate: ReadRegStr $R0 HKCR "LilyPond\shell\generate\command" "" ;;StrCmp $R0 "" 0 ly_auto_file WriteRegStr HKCR "LilyPond\shell" "" "generate" WriteRegStr HKCR "LilyPond\shell\generate" "" "&Generate PDF ..." WriteRegExpandStr HKCR "LilyPond\shell\generate\command" "" \ '"$INSTDIR\usr\bin\lilypond-windows.exe" -dgui "%1"' ;; what's the difference between ly_auto_file and shell/open/command? ;;ly_auto_file: ReadRegStr $R0 HKCR "ly_auto_file\shell\open\command" "" ;;StrCmp $R0 "" 0 ly_generate WriteRegStr HKCR "ly_auto_file\shell" "" "open" WriteRegExpandStr HKCR "ly_auto_file\shell\open\command" "" '"$EDITOR" "%1"' ;;textedit_open: WriteRegStr HKCR "textedit" "URL protocol" "" ReadRegStr $R0 HKCR "textedit\shell\open\command" "" ;;StrCmp $R0 "" 0 exit WriteRegStr HKCR "textedit\shell" "" "open" WriteRegExpandStr HKCR "textedit\shell\open\command" "" '"$INSTDIR\usr\bin\guile.exe" -e main -s "$INSTDIR\usr\bin\lilypond-invoke-editor.scm" "%1"' ;;exit: FunctionEnd Function postinstall_lilypad StrCpy $0 "$INSTDIR\usr\bin\lilypad" CopyFiles /silent "$0.exe" "$0-unicode.exe" ClearErrors ReadRegStr $R0 HKLM \ "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion IfErrors dos exit dos: CopyFiles /silent "$0-ascii.exe" "$0.exe" exit: FunctionEnd Function postinstall_lilypond StrCpy $0 "$INSTDIR\usr\bin\variables.sh" ${SubstituteAtVariables} "$0.in" "$0" # use console version for gui too StrCpy $0 "$INSTDIR\usr\bin\lilypond" ClearErrors ReadRegStr $R0 HKLM \ "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion IfErrors dos exit dos: CopyFiles /silent "$0-windows.exe" "$0-windows-orig.exe" CopyFiles /silent "$0.exe" "$0-windows.exe" StrCpy $0 "$INSTDIR\usr\bin\lilypond-windows.bat" ${SubstituteAtVariables} "$0.in" "$0" exit: FunctionEnd Function registry_guile ReadRegStr $R0 HKLM "${ENVIRON}" "PATHEXT" ${StrLoc} $0 $R0 ".SCM;" > StrCmp $0 "" 0 scm_done WriteRegStr HKLM "${ENVIRON}" "PATHEXT" ".SCM;$R0" scm_done: WriteRegStr HKCR ".scm" "" "GUILE" WriteRegStr HKCR ".scm" "GUILE" "GUILE" WriteRegStr HKCR ".scm" "Content Type" "text/x-guile" ReadRegStr $R0 HKCR "GUILE\shell\open\command" "" ;;StrCmp $R0 "" 0 exit WriteRegStr HKCR "GUILE\shell" "" "open" WriteRegExpandStr HKCR "GUILE\shell\open\command" "" '"$INSTDIR\usr\bin\guile.exe" -e main -s "%1"' exit: FunctionEnd Function registry_python ReadRegStr $R0 HKLM "${ENVIRON}" "PATHEXT" ${StrLoc} $0 $R0 ".PY;" > StrCmp $0 "" 0 py_done WriteRegStr HKLM "${ENVIRON}" "PATHEXT" ".PY;$R0" py_done: WriteRegStr HKCR ".py" "" "Python" WriteRegStr HKCR ".py" "Python" "Python" WriteRegStr HKCR ".py" "Content Type" "text/x-python" ;;py_open: ReadRegStr $R0 HKCR "Python\shell\open\command" "" ;;StrCmp $R0 "" 0 py_auto_file WriteRegStr HKCR "Python\shell" "" "open" # %1 is the PYTHON command, so must be quoted bo the space WriteRegExpandStr HKCR "Python\shell\open\command" "" '"$INSTDIR\usr\bin\python.exe" "%1" %2 %3 %4 %5 %6 %7 %8 %9' ;;py_auto_file: ReadRegStr $R0 HKCR "py_auto_file\shell\open\command" "" ;;StrCmp $R0 "" 0 py_end WriteRegStr HKCR "py_auto_file\shell" "" "open" # %1 is the PYTHON command, so must be quoted bo the space WriteRegExpandStr HKCR "py_auto_file\shell\open\command" "" '"$INSTDIR\usr\bin\python.exe" "%1" %2 %3 %4 %5 %6 %7 %8 %9' ;;py_end: FunctionEnd Function find_editor StrCpy $R0 "$WINDIR\emacs.exe" ifFileExists $R0 exit StrCpy $R0 $WINDIR\jedit.bat ifFileExists $R0 0 lilypad StrCpy $R0 "$R0 %(file)s +line:%(line)s" lilypad: StrCpy $R0 "$INSTDIR\usr\bin\lilypad.exe" ifFileExists $R0 exit StrCpy $R0 "$WINDIR\wordpad.exe" ifFileExists $R0 exit StrCpy $R0 "$WINDIR\NOTEPAD.EXE" exit: StrCpy $EDITOR "$R0" 0 0 FunctionEnd