Win32 Custom Product Building


If you want to build a product based on Squeak you can easily modify the image and virtual machine to suite your needs. This page provides some basic tips for customizing an application.

Preparing the image

First load the sourcecode of your application (game, webserver application) into a clean Squeak image file. Depending on the expected size of the image file you may want to unload or remove packages and classes that are not required at runtime (this process is called "stripping" an image and can be automated by simple scripts). This can also include all the tools that are required for development (browsers, test runner, etc.). Take care what you remove and heavily test the image and application before you ship.

Tip: If the size of the image file does not matter it may be wise to keep all the development tools since it allows you to debug, change or fix your application even in a production scenario.

If you want to keep the size of the distribution small you may wish to deploy the prepared application without the changes and source file. Since Squeak searches for these files at startup by default you may want to disable the two preferences "warnIfNoSourcesFile" and "warnIfNoChangesFile" (go to help -> preferences -> general to access the preference browser)

You can now save the image with your application already started. Alternatively you can write a special launcher class that is called at image startup:


Object subclass: #ApplicationLauncher
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'MySqueakBasedApp'
Now implement a new method #startUp at the class side of this new class. Here you can execute whatever is required to launch your application:

startUp
    "Launch my killer application"
	...
Now register your launcher class to be called at image startup by executing the following code in a workspace:

Smalltalk addToStartUpList: ApplicationLauncher
When you now save your image your startup code should be called.


Building a custom virtual machine

Compiling the squeak virtual machine is easier as it sounds in the first place. You can even adapt the source code so a custom virtual machine is built. To accomplish this follow these steps:

You will now find a "MyApp.exe" (with the custom icon) and two external plugins ("FT2Plugin.dll" and "SqueakFFIPrims.dll") in the myappbuild\obj\vm directory. Depending on your knowledge in Squeak virtual machine generation you can tweak your VM as required.

Tip: To build professional looking icons for Win32 we would recommend the free IcoFX editor.

Building a distribution

Now that you have sucessfully prepared an image and built a custom virtual machine you can assemble your own distribution. First create a directory "myappdist" and copy the following files into it:

If you start the application by dragging the MyApp.image file onto the MyApp.exe file you will notice that a new file ("MyApp.ini") is automatically created. This file includes default settings for the application. You can adapt it according to the settings page. Depending on your requirements you can include the following additional lines:

WindowTitle="MyApp"
ImageFile=MyApp.image
The first one sets a custom text for the applications main window and the second one allows you to specify the image for easier and faster startup. The interesting thing here is that by setting "ImageFile" you can name the image the way you like - so it is possible to name the image myapp.dat for instance (and hide the fact that the application is built in Smalltalk)

To provide a custom splash screen that is shown at application startup just create a simple bitmap file (splash.bmp) using a drawing program and provide a few more lines in the INI file:

SplashScreen="splash.bmp"
SplashTitle="My simple application"
SplashTime=2000
Depending on your type of application (open source or not) you may want to additionally provide a file license.rtf.

You can now package and distribute your application folder as a simple ZIP or follow the next step to build a professional installer.

Building a professional looking setup

There are many (free) setup tools out there. They allow you to easily built setup wizards and define which files to copy onto a target machine. One option could be to use the free NSIS (Nullsoft Install System) Tool to write a setup script and compile it into an executable setup. The setup script is a simple text file with the *.nsi extension. Here are some basic steps to help you getting started:

  1. download and install the free NSIS installer package, here we use version 2.42 from http://nsis.sourceforge.net
  2. also download the file "ZIPDLL.zip" plugin from http://nsis.sourceforge.net/ZipDLL. This allows for better compression of the image file.
  3. extract the file ZipDLL.dll to directory "Plugins" in your NSIS installation
  4. extract ZipDLL.nsh to directory "Include" in your NSIS installation
  5. create a file "setup.nsi" file (see below) to your "myappdist" directory and compile it using NSIS (right click on the file and select "Compile NSIS script" from the context menu
  6. you should now have a "setup_myapp_0.0.0.1.exe" ready for distribution
Assuming that you have the following files in "myappdist" directory:

setup.nsithe install script
license.rtfA license file in RTF format
MyApp.datthe image file
MyApp.icothe icon used for the installer
MyApp.exethe custom virtual machine
MyApp.inithe settings file for the virtual machine
splash.bmpthe splash screen
SqueakFFIPrims.dllthe plugin for FFI (Foreign Function interface) calls
FT2Plugin.dllthe freetype plugin
welcome.bmpa welcome bitmap used in the setup wizard<(164 ☆ 314 pixel)/td>
header.bmpa header bitmap used in the setup wizard (150 ☆ 157 pixel)

the contents of the setup script setup.nsi may look like that:

/*************************************************************************
 *
 *  NSIS Setup script
 *
 * (c) 2009 by Squeak Community, All rights reserved
 *
 * Requires: NSIS 2.42 http://nsis.sourceforge.net
 *           ZIP DLL   http://nsis.sourceforge.net/ZipDLL
 *************************************************************************/

SetCompressor /SOLID lzma                                ;use LZMA algorithm

###################################
# Includes
###################################
!include "MUI.nsh"
!include "ZipDLL.nsh"

###################################
# Definitions
###################################
; General definitions
!define /date TIMESTAMP "%Y-%m-%d-%H-%M-%S"
!define PROVIDER "Squeak Community"
!define PRODUCT  "MyApp"
!define PRODUCT_LOWERCASE "myapp"
!define VERSION  0.0.0.1
!define URL      "http://www.squeak.org"
!define YEAR     "2009"
!define LAUNCHER "myapp.exe"

!define APP_NAME "${PRODUCT}"
!define REG_KEY  "SOFTWARE\${APP_NAME}"
!define MGROUP   "${PRODUCT}"

; SOURCE Definitions
!define SETUP_NAME "setup_${PRODUCT_LOWERCASE}_${VERSION}.exe"
!define OUTPUT_TARGET "${SETUP_NAME}"

; TARGET Definitions
!define TARGET_DIR "$LOCALAPPDATA\${PRODUCT}"

###################################
# Compiler commands
###################################
Name         "${PRODUCT}"
OutFile      "${OUTPUT_TARGET}"
InstallDir   "${TARGET_DIR}"                             ;Default installation
InstallDirRegKey HKCU "${REG_KEY}" ""                    ;Get installation  from registry if available
RequestExecutionLevel user                               ;Request application privileges for Windows Vista
BrandingText "${APP_NAME} Version ${VERSION}"            ;brand the installer so now NSIS stuff is shown
XPStyle      on
CRCCheck     on                                          ;do a CRC check
SetOverwrite on                                          ;force overwrite
SetCompress force                                        ;force compression


###################################
# Infos for Software control panel
###################################

VIProductVersion 0.0.0.1
VIAddVersionKey ProductName     "${APP_NAME}"
VIAddVersionKey ProductVersion  "${VERSION}"
VIAddVersionKey CompanyName     "${PROVIDER}"
VIAddVersionKey CompanyWebsite  "${URL}"
VIAddVersionKey FileVersion     ""
VIAddVersionKey FileDescription ""
VIAddVersionKey LegalCopyright  "(c) ${YEAR} by ${PROVIDER}"

###################################
# Modern User Interface settings
###################################
; Other Definitions
!define MUI_ICON   "myapp.ico"		    		    ; icon for the installer
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "header.bmp"         	    ; optional
!define MUI_WELCOMEFINISHPAGE_BITMAP "welcome.bmp"          ; optional
!define MUI_FINISHPAGE_NOAUTOCLOSE                          ; Do not automatically jump to the finish page, to allow the user to check the install log.
!define MUI_UNFINISHPAGE_NOAUTOCLOSE                        ; Do not automatically jump to the finish page, to allow the user to check the uninstall log.
!define MUI_FINISHPAGE_RUN "$INSTDIR\${LAUNCHER}"	    ; allows to run the application after install

###################################
# Pages
###################################

;Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "license.rtf"
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH

;Uninstaller pages
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

###################################
# Language
###################################
!insertmacro MUI_LANGUAGE "English"

###################################
# Installer section
###################################
Section "Application" Section1
  SetOutPath "$INSTDIR"
  SetOverwrite on
  DetailPrint "Installation Started."

  File license.rtf
  File MyApp.exe
  File MyApp.dat
  File MyApp.ini
  File splash.bmp
  File SqueakFFIPrims.dll
  File FT2Plugin.dll

  ;Store installation
  WriteRegStr HKCU "${REG_KEY}" "" $INSTDIR
  ;Create uninstaller
  WriteUninstaller "$INSTDIR\Uninstall.exe"

  SetOutPath $INSTDIR
  DetailPrint "Create Program group"
  CreateDirectory "$SMPROGRAMS\${MGROUP}"
  CreateShortCut "$SMPROGRAMS\${MGROUP}\${PRODUCT}.lnk" "$INSTDIR\${LAUNCHER}"
  CreateShortCut "$SMPROGRAMS\${MGROUP}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"

SectionEnd

###################################
# Section description
###################################
LangString DESC_Section1 ${LANG_ENGLISH} "The sample application"
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
  !insertmacro MUI_DESCRIPTION_TEXT ${Section1} $(DESC_Section1)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

###################################
# Uninstaller section
###################################
Section "Uninstall"

SetOutPath $INSTDIR
    DetailPrint "Start uninstalling"

    Delete "$INSTDIR\license.rtf"
    Delete "$INSTDIR\MyApp.exe"
    Delete "$INSTDIR\MyApp.dat"
    Delete "$INSTDIR\MyApp.ini"
    Delete "$INSTDIR\splash.bmp"
    Delete "$INSTDIR\SqueakFFIPrims.dll"
    Delete "$INSTDIR\FT2Plugin.dll"

    ;delete uninstaller
    Delete "$INSTDIR\Uninstall.exe"
    RmDir /r /REBOOTOK "$SMPROGRAMS\${MGROUP}"
    RmDir /REBOOTOK $INSTDIR
    DeleteRegKey /ifempty HKCU "${REG_KEY}"
SectionEnd

#################################
# Utilities
#################################

# Installer functions
Function .onInit
    InitPluginsDir
    Push $R1
    File /oname=$PLUGINSDIR\spltmp.bmp splash.bmp
    advsplash::show 3000 600 400 -1 $PLUGINSDIR\spltmp
    Pop $R1
    Pop $R1
FunctionEnd

More tips and tricks