1). Let the user of your script to be responsible for locating and installing his own REXX interpreter.
OR
2). Wish to create an all-in-one package that includes your script as well as the REXX interpreter, thereby making it a no-brainer to get REXX installed upon his system and your script running.
For case #1, you don't need to include some additional files, which can be hundreds of K in size. You need distribute only your script. But then, the user has to locate and install a REXX interpreter himself.
For case #2, the user doesn't even need to know that your software is using REXX, and he has minimal hassle in getting your software to run because everything is included and will automatically install itself the first time he runs your software.
It all boils down to whether you want to make it easier for him, or easier for you.
Case #1: User does the work
For case #1, you should at least inform the user that he needs to install a REXX interpreter on his system, and recommend where he can find one. You could have this information on a web page where he downloads your script. Or you could have this information in a "readme.txt" text file included upon a CDROM or downloadable ZIP file which also contains your script.
Case #2: You do all the work
For case #2, you can distribute your package in two ways. You can create an auto-run CDROM. This CDROM contains your script and all the interpreter files. When the user puts the CDROM in the drive, the operating system installs REXX (if REXX isn't already installed upon his computer), and then REXX immediately runs your script off of the CDROM.
Alternately, your package can consist of a self-extracting ZIP file to be downloaded from the internet. This zip file contains your script and all the interpreter files. When the user clicks on the ZIP, the operating system automatically extracts the files and installs REXX (if REXX isn't already installed upon his computer), and then REXX immediately runs your script off of the hard drive (ie, wherever the files were extracted).
We'll discuss each of the two packages separately.
Note: If you wish to create such a package, then it is best to limit your support to the Reginald REXX interpreter. Other interpreters do not support some of the extra features that make it possible to create the self-installing packages described below.
An auto-run CDROM
If you're writing a REXX script that you'll be distributing on a CDROM, Reginald's Script Launcher makes it possible to create an auto-run CDROM that contains a REXX script. The launcher is smart enough to recognize when Reginald is not yet installed, and will therefore first run REGINALD.EXE to install Reginald. Then, it will run your REXX script on the CDROM. Do the following:
1). Place your completed REXX script in the root directory of the CDROM.
2). Place all of your help book files and their contents files, and any data files used by your script, in the root directory of the CDROM.
3). Place Reginald's REXX Script Launcher in the root directory of the CDROM. Its filename is RXLAUNCH.EXE and was installed upon your system when you installed Reginald (in the directory where you specified Reginald's program files to be installed).
4). Place the Reginald install utility in the root directory of the CDROM. Its filename is REGLITE.EXE (or REGINALD.EXE for the old version of Reginald) and it is the program you ran to install Reginald upon your system.
5) Create a text file (using Notepad or Rexx Programmer Center) named AUTORUN.INF that contains the following text:
open=rxlaunch.exe yourscriptname...where yourscriptname is the filename of your REXX script, for example myscript.rex (enclosed in double quotes if there are spaces in the filename).
Place this AUTORUN.INF file in the root directory of the CDROM.
6). If you need any extra DLLs such as REXX GUI, then create a directory named RexxDlls on the CDROM. Into this RexxDlls directory, copy the install utilities for any REXX function libraries your script uses. For example, the install utility for REXX GUI is named RExXGUI.EXE, which you used to install REXX GUI upon your system. If a function library that you're using does not have an install utility, then just copy the dll file itself to the RexxDlls directory.
You have now created a CDROM that will autorun your REXX script, even if REXX is not yet installed upon the system. The first time that the user inserts the CDROM in his drive, he will be prompted to install Reginald and all of the libraries in the RexxDlls directory, and then after installation, your REXX script will automatically run. The next time he inserts the CDROM, your REXX script will automatically run as it normally would (ie, the user won't be prompted to install Reginald again, since it is already installed) with no startup speed penalties incurred.
I recommend that you first create the above CDROM upon CD/RW media, so you can ensure that you have not forgotten to include any needed files. After testing, then you can burn a CD-R.
Incidentally, the Reginald installer itself is also smart enough to recognize when Reginald is already installed, and does proper version-checking so that older versions do not overwrite newer versions, and has the option to not re-install Reginald if a suitable version is already installed. So, if a suitable version of Reginald is already installed, your REXX script autoruns the very first time without even needing to prompt the user to install REXX.
A ZIP file
If you're writing a REXX script that you want to make downloadable from the internet, I recommend that you create a self-extracting ZIP file. Put RXLAUNCH.EXE, REGLITE.EXE, your help/data files, and your REXX script in it. Put any DLL installers that you need in a directory named RexxDlls and put this directory in the zip file (make sure that you include the relative path of RexxDll). For example, zip up "RexxDlls/REXXGUI.EXE".
Now set the self-extracting ZIP file to automatically run RXLAUNCH.EXE and pass it the name of your REXX script.
This will cause Reginald's Script Launcher to automatically install Reginald and all of the needed DLLs when the archive is unzipped, if Reginald is not yet installed, and then run your script.
Case #2: Extra installation done by your script
When Reginald REXX is installed, it doesn't copy your script off of the CDROM and onto the user's hard drive. So, the user must insert the CDROM whenever he wishes to run your script (although he will be prompted to install REXX only the first time).
Nor does REXX automatically copy your script from where it was extracted from the ZIP file to some other place on the hard drive. So, your script may be left in some temp directory (and may run the risk of being accidentally deleted). Also, REXX doesn't create an icon (ie, shortcut) on the desktop for the script, so unless the user extracts the ZIP file to his desktop, he will have to locate your script's icon by rummaging around in "My Computer" and double-clicking upon it to start your script.
So, if you want to copy your script (and any help/data files it needs) to some permanent place on his hard drive, such as his "Program Files" directory, and create a desktop icon (ie, shortcut) he can click upon to run your script, your script will have to do this itself.
Of course, if your script is going to copy itself to the hard drive (ie, install itself), then it should also give the user the option of later deleting everything you've copied. One approach is to add a name in Control Panel's "Add/Remove Programs" utilities, and when the user selects this, it will run some other script you've written to uninstall your software.
To take this approach, you'll have to create a directory of your own creation in the registry, inside the registry directory HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall. Then inside this new directory, you'll create a registry file named "DisplayName" whose contents is the string displayed by Add/Remove Programs. You'll also create a registry file named "UninstallString" whose contents is the full pathname of your uninstall script.
Whenever your main script runs, you can check if this registry directory exists. If it doesn't, you'll know that your script is running for the first time, and you need to install your script. First, you'll ask the user where he wants to install your software (ie, main script, uninstall script, and any help/data files). Then you'll create this directory, and copy your main script, uninstall script, and any help/data files to this directory. You'll also create a desktop icon. Finally, you'll use the VALUE() function to create the registry items so that not only can the user uninstall your software, but also the next time your main script runs, it can verify that it has already been installed.
REXX GUI has a function to create a shortcut. And Reginald has functions to read/write registry keys (VALUE), get the location of the "Program Files" directory or the current user's Desktop (SEARCHPATH), create directories (DIR), and copy files (COPYFILE).
Here's an InstallMyScript function you can call from within your main script to install your software. It is passed the name you would like to use for your registry directory (and default program files directory), the name you would like for your desktop icon, the name of your uninstall script, and the names of any additional help/data files. Note that InstallMyScript also registers the REXX GUI functions (thus relieving you of having to do that if you call InstallMyScript at the start of your script).
InstallMyScript: PROCEDURE /* Let's make sure that REXX GUI's functions are registered. We * need REXX GUI to create a desktop shortcut anyway, so let's * also register REXX GUI for our script's benefit. */ LIBRARY rexxgui /* Check if our "DisplayName" registry file exists. */ keyname = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\" || ARG(1) || '\' IF VALUE(keyname, 'DisplayName', 'WIN32') == "" THEN DO /* It doesn't exist. You must install. */ /* Here, you prompt the user where to install. Use REXX GUI's Directory dialog. */ mydir = SEARCHPATH('%PROGRAMS%') error = GUIFILE('MYDIR', 'BROWSE|DRIVES|NEWFOLDER', 'Where to install ' || ARG(2), , ARG(1)) IF error \== "" THEN RETURN IF mydir = "" THEN mydir = SEARCHPATH('%PROGRAMS%') || ARG(1) || '\' ELSE IF RIGHT(mydir, 1) \= '\' THEN mydir = mydir || '\' /* Create that dir. */ error = DIR(mydir) IF error \== "" THEN DO BadInstall1: GUISAY(error) RETURN END /* Copy this script. */ PARSE SOURCE . . orig error = COPYFILE(orig, mydir || '*.*', 'R') IF error \== "" THEN DO BadInstall2: DIR(mydir, 'D') SIGNAL BadInstall1 END /* Copy the uninstall script. */ error = COPYFILE(FILESPEC('D', orig) || FILESPEC('P', orig) || ARG(3), mydir || ARG(3), 'R') IF error \== "" THEN DO BadInstall3: DELETEFILE(mydir || FILESPEC('N', orig)) SIGNAL BadInstall2 END /* Copy help/data files, if any. */ i = 3 DO WHILE ARG(i + 1) \= "" error = COPYFILE(FILESPEC('D', orig) || FILESPEC('P', orig) || ARG(i + 1), mydir || ARG(i + 1), 'R') IF error \== "" THEN DO BadInstall4: DO WHILE i > 3 DELETEFILE(mydir || ARG(i)) i = i - 1 END DELETEFILE(mydir || ARG(3)) SIGNAL BadInstall3 END i = i + 1 END /* Create a shortcut named ARG(2) on the desktop. NOTE: You may * wish to ask him where to install this, and then create * that directory on the desktop. */ error = GuiMakeShortcut(mydir || FILESPEC('N', orig), SEARCHPATH('%DESKTOP%') || '\' || ARG(2) || '.lnk') IF error \== "" THEN DO DELETEFILE(mydir || EDITNAME(orig, '*.hlp', 'ST')) SIGNAL BadInstall4 END DO /* Create a registry directory named ARG(1). You can name it * whatever you desire, as long as it doesn't conflict with * an existing registry directory name. */ VALUE(keyname, , 'WIN32') /* Create a file named DisplayName under the above * directory and set its contents to the same as the name used * for the icon. */ VALUE(keyname || 'DisplayName', ARG(2), 'WIN32') /* Create a file named UninstallString under the above * directory and set its contents to run RXLAUNCH.EXE, * and pass the name of the uninstall script. */ error = VALUE("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\Reginald\UninstallString", , 'WIN32') VALUE(keyname || 'UninstallString', FILESPEC('D', error)||FILESPEC('P', error)||'RXLAUNCH.EXE "'||mydir||ARG(3)||'"', 'WIN32') /* Trap SYNTAX in case we fail to create the registry items above. */ CATCH SYNTAX CONDITION("M") END END /* Registry key doesn't exist. */ BadInstall: RETURNHere's how you may call InstallMyScript to install your script using a registry directory name of "MyScript" (and a default directory name of "MyScript"), create a desktop icon named "My Script", and list "My Script" under Control Panel's "Add/Remove Programs" to run the script "remove.rex".
InstallMyScript("MyScript", "My Script", "remove.rex")If you had extra help/data files, you'd simply list each one separated by a comma. For example, assume we have two more files to copy named "MyScript.hlp" and "mydata".
InstallMyScript("MyScript", "My Script", "remove.rex", "MyScript.hlp", "mydata")Of course, you'll need to write the 'remove.rex' uninstall script. Here is an UninstallMyScript function to call from within your uninstall script. It is passed the name you used for your registry directory (ie, the first arg you passed to InstallMyScript above), the name you used for your desktop icon (ie, the second arg you passed to InstallMyScript above), the name of your main script (ie, the one in which you placed InstallMyScript above), and the names of any additional help/data files.
UninstallMyScript: PROCEDURE /* Get the full path name of this script. We can then use that to * determine where the main script and other files were copied. */ PARSE SOURCE . . mydir /* Delete this script. */ DELETEFILE(mydir) /* Trim off the script name to get the place where the other * files were also copied. */ mydir = FILESPEC('D', mydir) || FILESPEC('P', mydir) /* Delete the main script. */ DELETEFILE(mydir || ARG(3)) /* Delete any additional files. NOTE: If you copied a .hlp * file, and the user has opened it, then Windows automatically * creates a file with a .gid extension. So, you may want to also * make sure you include any .gid filename to delete. */ i = 4 DO WHILE ARG(i) \= "" DELETEFILE(mydir || ARG(i)) i = i + 1 END /* Now that the directory may be empty, let's delete it. NOTE: * The directory will not be deleted if it is not empty. */ DIR(mydir, 'D') /* Delete our "DisplayName" registry file. */ keyname = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\" || ARG(1) || '\' VALUE("", keyname || 'DisplayName', 'WIN32') /* Delete our "UninstallString" registry file. */ VALUE("", keyname || 'UninstallString', 'WIN32') /* Delete our registry directory. */ VALUE("", keyname, 'WIN32') /* NOTE: We haven't deleted the shortcut on the desktop. Let * the user do that since he may have moved it somewhere. */ RETURNHere's how you may call UninstallMyScript to remove your software using a registry directory name of "MyScript", a desktop icon named "My Script", and a main script named "MyScript.rex".
UninstallMyScript("MyScript", "My Script", "MyScript.rex")