Arjen Markus (4 november 2003) I have put this little script on the Wiki, because questions as to how to deal with "installations" came up on the starkit mailing list.
The idea is simple:
So here is an example:
./install.vfs/ main.tcl lib/ app-install/ install.tcl pkgIndex.tcl <--- All standard starkit stuff! myapp/ <--- Copy of the directory to hold all bin/ files in the application exe1 exe2 lib/ config1 config2 config3 data/ mydata
When you create a starkit/starpack from this directory structure, all the files get copied into it. You can reach them via:
# # At the global level - otherwise [info script] does not return the # proper directory (It is the location of "install.tcl" we need) # set scriptdir [file dirname [info script]] # # Now we have stored the script's location, we # can manipulate it to reach our application directory # set appdir [file join $scriptdir ".." ".." "myapp"]
The procedure is really simple and straightforward:
You will need to customise the various bits and pieces but this is the gist of my installation script.
Note: For reasons unknown to me it sometimes takes a long time for it to finish copying the files out of the virtual directory. The files are there on disk, but the script is still processing the copy action.
Note: I have removed references to my specific software - not that is terribly confidential, but it is terribly irrelevant :).
Note: I use "mysomething" for all the things that need customisation (or removal).
package provide app-install 1.0 # install.tcl -- # "Install" myapp # # The procedure is very simple: # - Allow the user to select a directory for installation # - Copy the files from the starkit/myapp directory into the # directory on disk # - Create the new menu in the Start menu (assuming we are # on Windows) # package require Tk # fillCanvas -- # Fill the canvas with a picture and some text # # Arguments # cnv Canvas widget # cnv2 Second canvas widget # Results # None # Side effects: # Canvas filled # proc fillCanvas { cnv cnv2 } { image create photo logo -file [file join [file dirname [info script]] mybanner.gif] $cnv create image 0 0 -image logo -anchor nw $cnv2 create text 20 5 -text "My app:" -anchor nw $cnv2 create text 20 25 -text "Dedicated software" -anchor nw $cnv2 create text 20 45 -text "for your eyes only" -anchor nw $cnv2 create text 20 65 -text "NO WARRANTIES" -anchor nw $cnv2 create text 20 85 -text "(c) Me" -anchor nw } # showInfo -- # Show some textual information # # Arguments # None # Results # None # Side effects: # Message window with short information # proc showInfo {} { tk_messageBox -parent . -icon info -title "My app - information" \ -message { Whatever text you want to show .... } } # selectDir -- # Select the directory for installation # # Arguments # None # Results # None # Side effects: # # proc selectDir {} { global installdir set prevdir $installdir set installdir [tk_chooseDirectory -initialdir $installdir -parent . \ -title "Select a directory to install into" -mustexist 0] if { $installdir == "" } { set installdir $prevdir } } # copyFiles -- # Recursively copy files from one directory to the target, # to avoid problems with existing directories etc. # # Arguments # sourcedir Source directory # targetdir Target directory # Results # None # proc copyFiles { sourcedir targetdir } { foreach file [glob [file join $sourcedir *]] { if { [file isdirectory $file] } { set newsource $file set newtarget [file join $targetdir [file tail $file]] copyFiles $newsource $newtarget } else { file copy -force $file "$targetdir" } } } # installCourse -- # Install the course material # # Arguments # None # Results # None # proc installApp {} { global scriptdir global installdir set orgcursor [. cget -cursor] . configure -cursor watch set appdir [file join $scriptdir ".." ".." "myapp"] # # Check whether the installation directory is already there. # If not, create it first. # Check if there is a file. If # not, create a dummy file. # The reason: # - glob will complain otherwise # - glob -nocomplain causes a different behaviour for # directories with no subdirectories (at least on Windows XP) # if { ! [file exists $installdir] } { file mkdir $installdir } set contents [glob -nocomplain [file join $installdir *]] if { [llength $contents] == 0 } { set dummyfile [open [file join $installdir dummy] "w"] close $dummyfile } if { [file exists [file join $installdir waq]] } { foreach file [glob [file join $installdir waq *]] { file delete -force $file } } foreach file [glob [file join $appdir *]] { file copy -force $file $installdir } cd $installdir # # Add "My App" to the Start menu # file copy -force [file join $scriptdir "myapp.ico"] "." set curdir [file join [pwd] bin] set workdir [file normalize $curdir] set progfile [file nativename [file join $curdir myapp1.exe]] set iconfile [file nativename [file join $curdir "myapp.ico"]] progman_creategroup "My app" progman_additem "$progfile" \ "My app 1" "$iconfile" "$workdir" progman_additem "[file nativename [file join $curdir myapp2.exe]]" \ "My app 2" "$iconfile" "$workdir" tk_messageBox -message "Installation completed" .cancel configure -text "Exit" #exit } # main -- # Get the whole thing started # global scriptdir global installdir wm title . "MY APP" wm iconbitmap . -default [file join [file dirname [info script]] "myapp.ico"] canvas .canvas -height 90 -width 400 -background white canvas .disclaim -height 120 -width 150 fillCanvas .canvas .disclaim label .ltext -text "Install in:" label .empty1 -text " " label .empty2 -text " " entry .edir -textvariable installdir button .dirsel -text "Browse" -command selectDir -width 10 button .info -text "Info" -command showInfo -width 10 button .install -text "Install" -command installCourse -width 10 button .cancel -text "Cancel" -command exit -width 10 grid .canvas - - - -sticky ws grid .ltext - - .disclaim -sticky ws -padx 10 grid .edir .dirsel - ^ -sticky ws -pady 4 -padx 10 grid .empty1 - - - grid .install - .cancel .info -padx 10 -pady 10 # # Some global stuff to take care of # set scriptdir [file dirname [info script]] set installdir "C:/myapp" source [file join [file dirname [info script]] "progman.tcl"]