A Simple Installer for Palm Applications: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
m (Updated author links.) |
m (Updated author links.) |
||
Line 2: | Line 2: | ||
|<small>Author: [[{{ns:2}}:ellocogato|ellocogato]] ([[{{ns:3}}:ellocogato|talk]], [[{{ns:-1}}:Contributions/ellocogato|contrib]])</small> | |<small>Author: [[{{ns:2}}:ellocogato|ellocogato]] ([[{{ns:3}}:ellocogato|talk]], [[{{ns:-1}}:Contributions/ellocogato|contrib]])</small> | ||
|} | |} | ||
<br style="clear:both;">== Disclaimer == | <br style="clear:both;"> | ||
== Disclaimer == | |||
I am not particularly experienced with NSIS. I don't fully understand InstallOptions, the System plugin, or the Modern Interface. I needed an installer for a Palm application, and I could find no such existing NSIS example, so after hacking up an installer myself, I wrote an example based on what I did. It's probably not the most elegant, and it may not even be entirely correct. But it works. | I am not particularly experienced with NSIS. I don't fully understand InstallOptions, the System plugin, or the Modern Interface. I needed an installer for a Palm application, and I could find no such existing NSIS example, so after hacking up an installer myself, I wrote an example based on what I did. It's probably not the most elegant, and it may not even be entirely correct. But it works. | ||
Revision as of 23:13, 29 April 2005
Author: ellocogato (talk, contrib) |
Disclaimer
I am not particularly experienced with NSIS. I don't fully understand InstallOptions, the System plugin, or the Modern Interface. I needed an installer for a Palm application, and I could find no such existing NSIS example, so after hacking up an installer myself, I wrote an example based on what I did. It's probably not the most elegant, and it may not even be entirely correct. But it works.
If you find a mistake, find a better way of doing something, or add functionality that others might find useful, send me comments so that I can improve this example
The Script
; DESCRIPTION: Example Installer for simple (i.e. no conduit program) Palm applications ; AUTHOR: Gus Scheidt ; COMPANY: InfoPOEM, Inc. ; EMAIL: gus :AT: infopoems :DOT: com ; REQUIRES: - The InstAide DLL from the Palm Conduit Development Kit ; (copy to the same directory as the .nsi file) ; - Originally compiled with NSIS v2.0b4 (MUI interface changed ; between 2.0b3 and 2.0b4, so it may have changed again since 2.0b4) ;Script loosely based on the MUI Basic Example Script Written by Joost Verburg ; declare variables Var PalmUserList Var UserChoice Var InstallStatus !define MY_PRODUCT "My Palm App" ;Define your own software name here !define MY_VERSION "v1.0" ;Define your own software version here !define MY_BUILD "1234" Name "${MY_PRODUCT} ${MY_VERSION} (build ${MY_BUILD})" ;Display name for installer !include "MUI.nsh" ;-------------------------------- ;Configuration ; Name of the resulting executable installer file OutFile "${MY_PRODUCT}.exe" ; I don't intend to install any files permenantly on the PC, so ; use the system temporary directory InstallDir "$TEMP\MyAppSetup" ;-------------------------------- ;Modern UI Configuration ; Show a license agreement page !define MUI_LICENSEPAGE ; Show a warning when the user cancels the install !define MUI_ABORTWARNING ; I'm using some custom pages !define MUI_CUSTOMPAGECOMMANDS ; Show a finish page at the end of the installation !define MUI_FINISHPAGE ; Don't present the option to reboot the computer on the finish page !define MUI_FINISHPAGE_NOREBOOTSUPPORT ; The icon for the installer title bar and .exe file ;!define MUI_ICON "myapp.ico" ; I want to use my product logo in the installer ;!define MUI_HEADERIMAGE ; Here is my product logo ;!define MUI_HEADERIMAGE_BITMAP "myapp.bmp" ; I want the logo to be on the right side of the installer, not the left ;!define MUI_HEADERIMAGE_RIGHT ; I've written a function that I want to be called when the user cancels the installation !define MUI_CUSTOMFUNCTION_ABORT myOnAbort ; Override the text on the Finish Page !define MUI_FINISHPAGE_TITLE "Installation Complete" !define MUI_FINISHPAGE_TEXT "My Palm App has been installed to your Palm device. Click Finish now to close the installation program." ;-------------------------------- ;Pages ; These are the pages that I want my installer to consist of, in the order ; I want them to appear !insertmacro MUI_PAGE_LICENSE "License.txt" ; License agreement page. Use license text from License.txt !insertmacro MUI_PAGE_INSTFILES ; File installation page Page custom ShowUserList ; My custom page for choosing the Palm user Page custom InstallFiles ; My custom page for scheduling files to be installed ; and informing the user that a HotSync is required ; I've written a function that I want to be called just before the finish page is displayed !define MUI_PAGE_CUSTOMFUNCTION_PRE myFinishPre !insertmacro MUI_PAGE_FINISH ; the Finish page ;-------------------------------- ;Languages ; I don't know anything about Internationalization. But I speak English !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ;Language Strings ;Description text that I want to appear while files are being copied LangString DESC_SecCopyUI ${LANG_ENGLISH} "Copying the Palm files to your computer so they can be installed to your device." ;Header text for all pages in the installer LangString TEXT_IO_TITLE ${LANG_ENGLISH} "My Palm App" LangString TEXT_IO_SUBTITLE ${LANG_ENGLISH} "Install the Application and Data Files to your Device" ;-------------------------------- ;Data ; Is this redundant LicenseData "License.txt" ;-------------------------------- ;Reserve Files ;Things that need to be extracted first (keep these lines before any File command!) ;Only useful for BZIP2 compression ReserveFile "showUserList.ini" ReserveFile "installFiles.ini" !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS ;-------------------------------- ;Installer Sections Section "MyApp.prc" SecCopyUI ; Define what files go where SetOutPath "$INSTDIR" File "MyApp.prc" File "MyAppData.dat" SectionEnd ;-------------------------------- ;Descriptions !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecCopyUI} $(DESC_SecCopyUI) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ;Installer Functions Function .onInit ;Extract InstallOptions INI Files !insertmacro MUI_INSTALLOPTIONS_EXTRACT "showUserList.ini" !insertmacro MUI_INSTALLOPTIONS_EXTRACT "installfiles.ini" ; Get a list of all Palm users on the PC Call GetPalmUserList ; Use this list to populate the dropdown on our custom page !insertmacro MUI_INSTALLOPTIONS_WRITE "showUserList.ini" "Field 3" "ListItems" "$PalmUserList" FunctionEnd Function ShowUserList !insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)" !insertmacro MUI_INSTALLOPTIONS_DISPLAY "showUserList.ini" ; if we are aborting, do not check the value of UserChoice (if we do, then ; if the user cancels the install without selecting a user, it will insist ; that the user choose a user before exiting) StrCmp $InstallStatus "aborting_ir_install" Continue 0 !insertmacro MUI_INSTALLOPTIONS_READ $UserChoice "showUserList.ini" "Field 3" "State" ; Verify that the user chose a valid user. If not, display the ShowUserList ; screen again. ; Why not simply set MinLen of the dropdown to 1? This will prevent the user ; from continuing without selecting a user, but it will not present any ; messagebox or other dialog. That is confusing to the user! StrCmp $UserChoice "" 0 Continue MessageBox MB_OK|MB_ICONINFORMATION "You must choose a user to proceed!" Call ShowUserList Continue: FunctionEnd Function InstallFiles ; Set the PRC file to be installed to internal memory on next HotSync StrCpy $1 $UserChoice StrCpy $2 "$INSTDIR\MyApp.prc" ;MessageBox MB_OK|MB_ICONINFORMATION "Installing $2 for user $1" System::Call 'InstAide::PltInstallFile(t r1, t r2) i .r3' ;MessageBox MB_OK|MB_ICONINFORMATION "PltInstallFile returned value of $3" ; Say our data file is big or is a file type that PalmOS doesn't allow on internal ; memory. Schedule the data file to be installed to the Expansion Card on next HotSync ; (Note that PltInstallFile uses username while PlmSlotInstallFile uses userID.) StrCpy $1 $UserChoice System::Call 'InstAide::PlmGetUserIDFromName(t r1, *i r4r4) i .r5' ; $4 contains UserID for the chosen user ; Some debugging stuff to follow what is going on ;MessageBox MB_OK|MB_ICONINFORMATION "UserID for $1 is $4 (result was $5)" ;StrCpy $3 ${NSIS_MAX_STRLEN} ; assign memory to $0 ;System::Call 'InstAide::PlmGetUserNameFromID(i r4, t .r7, *i r3) i .r5' ;MessageBox MB_OK|MB_ICONINFORMATION "UserName for $4 is $7 (result was $5)" ; Use Card 0. I don't really understand how card numbering works, so if a ; device has multiple expansion cards, this script will simply install to whichever ; happens to be numbered 0 StrCpy $6 0 ; Set the data file to be installed to external memory StrCpy $2 "$INSTDIR\MyAppData.dat" ;MessageBox MB_OK|MB_ICONINFORMATION "Installing $2 for user $4 ($7)" System::Call 'InstAide::PlmSlotInstallFile(i r4, i r6, t r2) i .r5' ;MessageBox MB_OK|MB_ICONINFORMATION "PlmSlotInstallFile returned value of $3" !insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)" !insertmacro MUI_INSTALLOPTIONS_DISPLAY "installfiles.ini" FunctionEnd Function GetPalmUserList ; NSIS has to be using the directory containing the dll for it to find it SetOutPath "$INSTDIR" File "InstAide.dll" ; copy dll there System::Call 'InstAide::PltGetUserCount(v) i .r1' ; MessageBox MB_OK|MB_ICONINFORMATION "There seem to be $1 Palm users" IntCmp $1 0 0 0 foundInstaller ; if return value of PltGetUserCount is 0 or negative, then we can't continue MessageBox MB_OK|MB_ICONINFORMATION "No Palm Installer was found on your system. The installation cannot complete. Please ensure that the latest version of the Palm Desktop Software is installed on your computer before installing." Abort foundInstaller: ; Compile the list of Palm Users StrCpy $2 0 ; Initialize counter Loop: StrCpy $4 ${NSIS_MAX_STRLEN} ; $4 will tell the function the buffer length of $3 ; $3 will be set to the username of the user indexed by $2 System::Call 'InstAide::PltGetUser(i r2, t .r3, *i r4) i .r5' StrCpy $PalmUserList "$PalmUserList$3|" IntOp $2 $2 + 1 ; Incriment the counter IntCmp $2 $1 0 Loop 0 ;user list built, but it has an extra | on the end of it StrCpy $PalmUserList "$PalmUserList" -1 FunctionEnd Function RemoveFiles ; We need to Unload the dll so that it can be deleted System::Call 'InstAide::PltGetUserCount(v) i .r1 ?u' ; I read somewhere that you should do this. Don't know what it does SetPluginUnload manual System::Free 0 ; Remove all of the files Delete "$INSTDIR\InstAide.dll" RMDir /r "$INSTDIR" FunctionEnd Function RemoveInstallFiles ; Un-schedule the PRC file for installation to internal memory StrCpy $1 $UserChoice StrCpy $2 "MyApp.prc" System::Call 'InstAide::PltRemoveInstallFile(t r1, t r2) i .r3' ;MessageBox MB_OK|MB_ICONINFORMATION "PltRemoveInstallFile returned value of $3" ; Un-schedule the data file for installation to external memory System::Call 'InstAide::PlmGetUserIDFromName(t r1, *i r4r4) i .r5' ; $4 contains UserID for the chosen user StrCpy $6 0 StrCpy $2 "$INSTDIR\MyAppData.dat" System::Call 'InstAide::PlmSlotRemoveInstallFile(i r4, i r6, t r2) i .r5' FunctionEnd Function myFinishPre ; Before we exit the installer, clean up all of the files that we copied ; to the PC Call RemoveFiles FunctionEnd Function myOnAbort ; Let other parts of the installer know that we are aborting StrCpy $InstallStatus "aborting_ir_install" ; In case we've already scheduled files for installation on the next HotSync, ; we should un-schedule them Call RemoveInstallFiles ; Clean up all of the files that we copied to the PC Call RemoveFiles FunctionEnd
INI Files
Here are the .ini files that are referenced in the script
showUserList.ini
[Settings] NumFields=4 [Field 1] Type=Label Text=After you have selected a user, click "Next". Left=0 Right=171 Top=123 Bottom=132 [Field 2] Type=Label Text=STEP 1 -- Choose the User for Installation Left=85 Right=226 Top=4 Bottom=12 [Field 3] Type=Droplist Text=droplist ListItems= Left=60 Right=157 Top=74 Bottom=116 [Field 4] Type=Label Text=Select the user for whom you wish to install My Palm App from the dropdown box below. (Note that this script only supports installing for one user at a time. If you wanted to be able to select multiple users and have your program scheduled for installation on the next HotSync, you would have to change the dropdown box to a listbox and change the script to call the InstAide functions for each user selected.) Left=0 Right=272 Top=24 Bottom=69
installFiles.ini
[Settings] NumFields=3 [Field 1] Type=Label Text=You must now perform a HotSync to install My Palm App to your device.\r\n\r\nPerform a HotSync now. Left=0 Right=278 Top=24 Bottom=94 [Field 2] Type=Label Text=When the HotSync is complete, click "Next" below. Left=0 Right=181 Top=121 Bottom=129 [Field 3] Type=Label Text=STEP 2 -- Perform a HotSync Left=85 Right=185 Top=4 Bottom=12