Download
Download makedist
Description
MakeDist is a VBScript utility I use to automate Making a Distribution: it
makes a backup of the project, copys the executable and optionally the source
to my distribution folder, with unneeded files removed, and then zips
everything up. I wrote it so I'd stop making mistakes when putting distributions
together.
Usage
MakeDist is a VBScript text file. It is intended to be run from a Shortcut
(.lnk file) with its various command line parameters canned in the Shortcut.
makedist exeName projectFolder [otherFolder]... [/s[name]] [/d] [-name]...
In the Shortcut, set the current directory to contain the .\Backup folder,
and usually the project
folder. Set the parameters as needed.
The exeName
and the project
folder name are
required.
/s |
Distribute the source. |
/sname |
...naming the .zip file "name". |
/d |
Use the .exe's modified date instead of its version resource for the
backup folder name suffix. |
-name |
Omit files named "name" or extended ".name", or folders if "\name". |
otherFolder |
will be included in the backup and source distribution. |
For example, MakeDist is "makedist'ed" by a Shortcut containing a Target and
Start In:
"%userprofile%\My Documents\VC98 Projects\MakeDist\makedist.vbs"
MakeDist.vbs MakeDist /d -zip.exe
"%userprofile%\My Documents\VC98 Projects"
WMPVolKeys is "makedist'ed" by a Shortcut containing a Target and
Start In:
"%userprofile%\My Documents\VC98 Projects\MakeDist\makedist.vbs"
WMPVKeys.exe WMPVolkeys /s"WMPVolKeys Source" Common TrayButton
"%userprofile%\My Documents\VC98 Projects"
The .zip'ing is done with
Info-Zip's free zip.exe. I wasted quite a bit of time trying to do the job with
Windows' built-in Compressed Folder stuff (zipfldr.dll), but it's really
not documented, even though it's been around since Windows 98. Googling around
eventually turned up gzip, which led me to
Info-Zip.
Discussion
My first attempt at makedist was a batch file (see figure). The
result was almost satisfactory, though I couldn't find a command to get the
file version and had to write my own. The xcopy
command had a
handy feature, the /EXCLUDE
parameter, which made it easy to
strip out unneeded files. Well, fairly easy, as the list of files had to be
in a file itself, which the batch file made if missing. Learning all the
tricky parameter and variable expansion flags was sort of fun, as was
figuring out how to execute a command and set a variable to its output, by
using for
with the /f "usebackq"
flag to enable
the feature. All in all, a triumph of cryptic script.
Windows may depend on path names, but it doesn't handle them well,
certainly not in the Command Prompt (cmd.exe
). Many paths - even
short paths - require quoting, say, if the path contains an ampersand
("&"), but commands themselves can't be quoted. I eventually gave up on
batch files and turned to another scripting language, VBScript.
My VBScript version (see figure) handles paths
well, and path manipulation relies on method calls rather than command
expansion flags. Actually, VBScript itself doesn't operate on files at all,
but additional scripting objects such as the
Scripting.FileSystemObject
and WScript.Shell
do a
fine job of it. VBScript has some other limitations, such as lacking a useful
STOP
statement, but it does have various EXIT
statements, such as EXIT FOR
and EXIT SUB
, which
allow for reasonable code structure. It has only three variable types:
variants, objects, and arrays. Variables normally are assigned as implicit
LET
statements, but assigning an object to a variable requires a
SET
statement, for no good reason that I can find. Also, the
VBScript documentation is somewhat lacking, in that it assumes that VBScript
is just a subset of Visual Basic, without ever being explicit about what parts
of Visual Basic are included, such as statement continuation (with
"_
") or multiple statements (with ":
"). It also
lacks any form of I/O, so it can be a bit hard to tell when a script has
finished execution.
The code is structured as if it were in a "real language". Global variables
are defined at the top, then the various functions and subroutines, and finally
the main program at the bottom. VBScript doesn't require this, but it makes the
code and variable declarations easier to follow. All variables must be explicitly
declared, which allows VBScript to warn me about misspelled variable names.
The locations to put distributables and backups in are declared at the top
with the other
Global variables.
Distributables have an absolute path, but backups are relative to the current
directory, a feature that might come in handy later, though not so far. The
lists of files and folders to exclude are kept in strings, with entries
separated by a character that normally isn't allowed in a file name,
":
". The lists can be searched with the INSTR
function. The lists can be extended with command line parameters, which is
why they aren't declared CONST
. The two file system objects are
created. I needed both. The Scripting.FileSystemObject
had most
of what I needed, but the WScript.Shell
object has the current
directory, run, and timed message box stuff. The temporary directories are
declared here so they can be cleaned up properly on errors.
Argument parsing can be confusing, and
GetArgs
is the last of
several iterations. As structured now, parameters can be positional, or they
can be flags in any order, and flags can have additional data. GetArgs
only checks the syntax of the command line when it parses it, leaving semantic
checks for later. All the flags must be "real", and there must be at least
two positional parameters.
MakeDistImpl
does the work. First it validates the two
required positional parameters, the exe and the project, sets up paths, and then
copies the project and other folders to a temp directory, omitting various
files, by calling CopyFolderExclude
. It then zips up the copied
folders, changing the current directory so that only relevant path information
will be placed in the .zip file. It tries to report all errors and check
parameters enough that there won't be unexpected errors. I want unexpected
errors to be brought to my attention, so I don't use On Error Resume
Next
.
CopyFolderExclude
is a simple recursive directory copy routine
that iterates over the files and copys files that don't match the excludes list,
and then iterates over the directories and calls itself for any that don't match
the excludes list.
ZipIt
encapsulated running zip.exe as an external command. Flags
are set for recursive copying, quiet mode, and tight compression, and it is run
in a hidden window. We wait for completion so we can return a status code, and
anyway, running several cpu-intensive tasks at the same time won't be faster.