Other mind-blowing Windows work, Brian Beckman's full-metal-jacket windows native function interface. See http://www.angelfire.com/wa/brianbec/siodffi.html. At the end of this file, my notes on building crude windows-installers.
See also SIOD for MS-DOS.
Skip to: installation, support, or sources.
This distribution of the SIOD Scheme dialect of lisp language interpreter you may find useful for a number of reasons, including:
At this point you may make use of your new tool. The file siod.txt has information about the command lines switches. Use Wordpad to view the file, because it still has the unix-style end-of-line convention. Other txt files contain documentation on particular commands (smd) files. Use your web browser to view the documentation in siod.html.
Note the m and v flags to csiod. If you were going to create a cgi script, then you would use a different default "main" and "verbosity" level, such as:
> csiod :o=cgi-echo.exe :m=3 :v=0 cgi-echo.scm
For examples of CGI scripts see chtml.html.
See siodusers for info on the siod mailing list and some network references to users of siod. (About 10 years old).
See Scheme FAQ's for more reference material.
From time to time I push the thing to include more standard functions without increasing the runtime footprint very much. Beware that a high quality implementation of the full numerical tower of types and functions would double the size of the base system. Until some standard C or C++ library can be utilized instead of course.
Portions of this software are based in part on the http://alum.mit.edu/www/gjc/siod.html work of George J. Carrette.
Command line utilities with a -help option of some kind should also display the above phrase. Online and printed documentation should also contain that phrase in the obvious place along with similar notices.
The short notification phrase is sufficient and better than the longer notice suggested in the source code itself.
To compile you can use a full Visual Studio 2005 edition, or Visual C++ 2005 Express Edition. To build the installer you will need Windows Installer XML, version 2.0
The file BUILD.BAT invokes the VCBUILD program and also builds the installer, assuming all the tools have been installed in the standard places.
This example is obviously quite obsolete given the power and ease of use of Windows Installer XML. But recall that it was based on technology for windows NT version 4.
This example provides a subset of the standard siod distribution files, if needed, establishes the required windows registry entries for SIOD, and creates a new file type SSF, which with a OPEN action to invoke siod, and also an EDIT action. It provides some additional DLL's and a sample script and readme file.
If SIOD is already installed then it skips the siod registration.
You should be able to use this as a template for your own applications.
;;-*-mode:lisp-*- ;; name: setup.scm ;; purpose: source for SETUP.EXE for installation of SIOD subset ;; along with ECI script extension file. ;; created: 28-JUL-1999 George J. Carrette LITTON/TASC ;; ;; note: The commercial product installshield can do this much prettier. ;; As can a custom setup.exe created using visual C++ or ;; visual basic. (define *siod-dist-files* '("siod.exe" "csiod.exe" "wcsiod.exe" "slibw32.dll" "libsiod.dll")) (define *eci-dist-files* '("epshr02.dll" "eciclt32.dll")) (define *siod-eci-dist-files* '("siod_eci.dll" "ecisample.ssf" "readme.txt")) (define (fatal-setup-error . rest) (apply writes (cons nil rest)) (error "fatal setup error")) (define (main) (let ((result (*catch 'errobj (cons 1 (main-1)) nil))) (writes nil "Press Enter to exit ...") (readline))) (define *key* "SOFTWARE\\George Carrette\\SIOD") (define *dir* "C:\\SIOD") (define *ftype* "SSF") (define (main-1) (writes nil "*****************************************\n" "* ECI SIOD scripting language installer *\n" "* See README.TXT for more information *\n" "*****************************************\n" "\n") (require-so (so-ext 'slibw32)) (let ((inplace-siod-lib (siod-lib)) (key *key*) (root "HKEY_LOCAL_MACHINE") (value "SIOD_LIB") (registered-siod-lib nil) (new-siod-lib nil)) (*catch 'errobj (set! registered-siod-lib (registry-ref root key value))) (writes nil "\n") (cond ((equal? inplace-siod-lib registered-siod-lib) ;; if this setup.scm was compiled with :b=siod.exe ;; then this can happen. (fatal-setup-error "Improperly built SETUP.EXE\n"))) (writes nil "SETUP DIR = " inplace-siod-lib "\n") (cond (registered-siod-lib (writes nil "Installed SIOD LIB DIR = " registered-siod-lib "\n\n") (cond ((y-or-n-p (string-append "copy ECI files to " registered-siod-lib " directory?")) (install-files (append *eci-dist-files* *siod-eci-dist-files*) inplace-siod-lib registered-siod-lib)) ('else (fatal-setup-error "user chose not to install files\n")))) ((set! new-siod-lib (get-user-input "Installation Destination directory" *dir*)) (if (not (substring-equal? "\\" new-siod-lib (- (length new-siod-lib) 1) (length new-siod-lib))) (set! new-siod-lib (string-append new-siod-lib "\\"))) (or (y-or-n-p (string-append "copy ECI files to " new-siod-lib " directory?")) (fatal-setup-error "user chose not to install files\n")) (create-directory new-siod-lib) (install-files (append *eci-dist-files* *siod-eci-dist-files* *siod-dist-files*) inplace-siod-lib new-siod-lib) (registry-set root key value new-siod-lib)) ('else (fatal-setup-error "not implemented"))) (cond ((y-or-n-p (string-append "Register file extension " *ftype* " ? ")) (register-siod-ftype (registry-ref root key value))))) (writes nil "********\n" "* DONE *\n" "********\n" "\n")) (define (register-siod-ftype dir) (registry-set "HKEY_CLASSES_ROOT" (string-append "." *ftype*) "" (string-append *ftype* "_FILE")) (registry-set "HKEY_CLASSES_ROOT" (string-append *ftype* "_FILE") "" "SIOD script file") (registry-set "HKEY_CLASSES_ROOT" (string-append *ftype* "_FILE" "\\Shell\\open\\command") "" (string-append "\"" dir "siod.exe\"" "-v01,-m2 \"%1\" %*")) (registry-set "HKEY_CLASSES_ROOT" (string-append *ftype* "_FILE" "\\Shell\\Edit\\command") "" ;; we should actually get this value from the key ;; WordPad.Document.1\\Shell\Open\command. ;; or wrifile. (for .wri). (string-append "\"" (or (getenv "sysmtedrive") "C:") "\\Program Files\\Windows NT\\Accessories\\" "WORDPAD.EXE" "\"" " \"%1\""))) (define (y-or-n-p . msg) (let ((result nil) (return nil) (in nil)) (while (not return) (apply writes (cons nil msg)) (set! in (readline)) (cond ((not in) (fatal-setup-error "no input\n")) ((member (set! in (string-downcase (string-trim in))) '("y" "yes")) (set! return t) (set! result t)) ((member in '("n" "no")) (set! return t) (set! result nil)) ('else (writes nil "Please reply yes or no.\n")))) result)) (define (get-user-input msg default) (let ((result nil) (return nil) (in nil)) (while (not return) (writes nil msg " [" default "]: ") (set! in (readline)) (cond ((not in) (fatal-setup-error "no input\n")) ((equal? in "") (set! return t) (set! result default)) ('else (set! return in) (set! result nil)))) result)) (define (install-files l from into) (mapcar (lambda (x) (copy-one-file (string-append from x) (string-append into x))) l)) (define (copy-one-file from to) (let ((buff (cons-array 4096 'byte)) (in (fopen from "rb")) (out (fopen to "wb")) (nbytes nil)) (writes nil from " -> " to "\n") (while (set! nbytes (fread buff in)) (fwrite (if (= nbytes (length buff)) buff (list buff nbytes)) out)) (fclose in) (fclose out))) (define (create-directory name) (let ((old (getcwd))) (chdir (getenv "WINDIR")) ;; chdir prevents warning if cwd is an UNC (system (string-append "mkdir \"" name "\"")) (chdir old)))