Archive: A little undocumented feature of NSIS


A little undocumented feature of NSIS
As others have found as well, NSIS is proving to be a useful tool in ways unforseen by its designers. I got sidetracked from writing an installer for a product that I'm still developing, to experimenting with the capabilities of NSIS -- which I have yet to fully master. (It's a slow learning curve.) It suddenly occurred to me that I could use NSIS to create something that I have always wanted -- an interpretive batch-file processor for Windows, which would read a plain-text input file and execute commands that it finds there. (I used to be a DOS batch-file junkie back in the old days.) I know there are other products out there that do this (e.g. Batchrun, http://www.outertech.com), but not really well (IMO), so I am now trying to create one with NSIS that will have all the features I would like to see in such a utility. (Or the ones that I can successfully implement at any rate.) It's interesting to watch this thing grow. I'm calling it Batman. (And, if no input file is specified on the command line, it looks for a file named Robin.bmn. :D ) If it amounts to anything worthwhile, I may post the results of my work here.

In the process of developing it, I discovered an obscure but interesting feauture of NSIS, documented below. If anyone else finds this information useful, good luck to you.


OpenFile:
ClearErrors
DetailPrint `Attempting to open input file ($7).`
FileOpen $9 $7 r
IfErrors OpenError ProcessFile

ProcessFile: ; ------- P R O C E S S I N G I N P U T F I L E -------

DetailPrint `Input file ($7) opened. (Handle: $9)`
SetDetailsPrint TextOnly ; We display the inputfile's name on the status
DetailPrint $7 ; line, where it will stay because subsequent
SetDetailsPrint ListOnly ; command-logging is now to the listbox only.
StrCpy $9 `$9) $7` ; Explained below

; The above line makes use of an undocumented feature of NSIS (a useful one -
; not a bug) that deserves to be documented. Once a file has been opened, it
; is not necessary for internal operational purposes to retain the filename;
; only the filehandle (stored here in $9) is required. However, here, we want
; to retain the filename for possible use later on in information displayed
; for the benefit of the user. (See explanation above where Subcaption 4 is
; set.) But why waste a variable to retain it if there is another way to do
; so? (Variables are at a premium here, because $R1 to $R9 are reserved for
; use by the user.) I discovered that it is possible to append the filename
; (or other non-numeric text) to the variable holding the filehandle without
; impeding file I/O operations. It seems that once a valid filehandle is read
; from the relevant variable by the internal I/O routines they (sensibly)
; ignore other kinds of data that may be appended to the filehandle in that
; variable. This means that we can safely append other stuff there.

very good to know, the only problem is that you need to parse the handle now to get the file name back.


Indeed
Yup! As they say, "there's no such thing as a free lunch."


hehe, how true is that!


Since a handle is just a pointer to some Windows structure, it's nothing but a number. NSIS variables are kept as strings, and to get a number it must convert them. When converting it stops on the first character it finds if in decimal mode.


Hi,

I could use NSIS to create something that I have always wanted -- an interpretive batch-file processor for Windows, which would read a plain-text input file and execute commands that it finds there.
I must be missing something how is this different from a ".bat" or ".cmd" file?
A simple batch file will work anywhere.
NT/2000 and I assume XP have major (if cryptic) extensions which allow for quite complex processing...

If if you don't mind installing software "rexx" is good and I don't know about older operating systems but VBSCRIPT/JAVASCRIPT/WSH is available on Windows 2000/XP.

Bye,
Dennis