OLE – File handling

The executable includes a few demos / built-in functions that use OLE techniques to access the file system.


Writing text to a file:

The following script is a function that will copy the executable’s current input script, to a default file in a special folder used for temporary files belonging to this instance of the executable.. The script is built-in to the executable in the System macros Panel.

function WriteScriptToFile ( )
Dim objFSO = CreateObject("Scripting.FileSystemObject")
Dim objTextStream = objFSO.OpenTextFile(tmptxtFile , 2, 1)
objTextStream.write = script
objTextStream.Close
Set objTextStream = Nothing
Set objFSO = Nothing
WriteScriptToFile = tmptxtFile
end function

tmptxtFile is a keyword of the executable that is a read only string giving the name of a default file

scriptis a keyword of the executable that is a read only string giving the entire content of the current input script.

So place the following in the Edit Panel and execute it:

newscript
' comment line
writeScriptToFIle ()
' now send the default file, to the Windows default txt handler
system = tmptxtfile

system is a keyword of the executable that takes a single text string parameter and passes that string to the Windows system via the Windows API system .


List the files in the default folder (dir):

The following script will list all of the files in the default folder to a string variable, and then display the string in a message pop-up window.

The script uses  a  For each  ..   Next ..  command construct.

newscript
' Starts the Scripting.FileSystemObject
' Lists the files in the default directory
newscript
dim fso = createobject ("Scripting.FileSystemObject")
If ( ! fso ) THEN
Message ="Could not create object"
stop
End IF
dim objFolder = fso.getFolder( dir() )
dim myEnum = objFolder.files
dim myFile
dim i = 0
freestring = ""
For each myFile in myEnum
i = i + 1
freestring = freestring & i & " " & myFile.name & chr(0x0a)
Next myFile
message = freestring
' Finished


Get the serial number of the default system disk:

The following script is included for fun, it demonstrates the use of the commands  chr , asc and environ, and shows a somewhat exotic use of the OLE FileSystemObject

newscript
dim fsobj = CreateObject( "Scripting.FileSystemObject" )
message = fsobj.Drives .item( CHR ( asc ( environ ( "systemdrive" ) ) ) ) .Serialnumber
set fsobj = nothing

Script explanation:

environ is a keyword of the executable that takes a single string parameter and passes it to the Windows API getenv.   Examples:

environ ( "SYSTEMROOT" )  ' returns, on my PC, the string "C:\Windows"
environ ( "SYSTEMROOT" )  ' returns, on my PC, the string "C:"

In the script snippet, asc takes a string parameter and returns the first character of a text string as a integer value. In my case this is   67

chr converts an integer value to a single character string, so we get “C”

So the line:

message = fsobj.Drives .item( CHR ( asc ( environ ( "systemdrive" ) ) ) ) .Serialnumber

reduces to

message = fsobj.Drives .item( "C" ) .Serialnumber

Okay I was being a bit stupid using chr  and asc  the following would have worked just as well, actually better because it is more obvious what the code does.

newscript
dim fsobj = CreateObject( "Scripting.FileSystemObject" )
message = fsobj.Drives .item(   left( environ ( "systemdrive" ) ,1)   ) .Serialnumber
set fsobj = nothing

Left is an keyword of the executable that extracts a specified number of characters from the left end of a given string.

The fsobj.Drives .item expects a single character string identifying a valid disk-drive and accesses the appropriate drive object, the Serialnumber is a property of the drive object and returns the specified drive’s serial number. In my case -1964903990

How did I find all of this information, surf the web.


Creating a ZIP file:

In one project I had to take a database of about 500 thousand lines, ~ 100 columns and split it based on a given column (~ 300 different values). For each value the relevant rows were to be further split in to 2, based on another column. Each “split” was then to be written to an Excel file. So at the end there were approximately 600 files.

I then had to  place the file pair in a ZIP file whose name was derived from the ~ 300 values! So ~ 300 ZIP files.

The following script snippet shows the function used to create the ZIP files. The function CreateEmptyZipFolder is in the System macro Panel.

function CreateEmptyZipFolder ( FileName )
' create an empty ZIP folder into which you can *copy* files
dim zfb = byteArray ( 22 , 80 , 75, 5, 6)
Dim BinaryStream = CreateObject("ADODB.Stream")
BinaryStream.Type = 1
BinaryStream.Open
BinaryStream.Write (zfb)
BinaryStream.SaveToFile( FileName, 2)
BinaryStream.close
End Function

I found out that an empty ZIP file contains 22 bytes, of which the first 4 have the values 80 , 75 , 5 , 6.

So I created a variable, a byte array of 22 bytes, and initialized it:

dim zfb = byteArray ( 22 , 80 , 75, 5, 6)

Then I used the ADODB.Stream object to create an empty file, and insert my 22 bytes in to it. Save the file with the appropriate file name and finish.


I shall now use parts of the previous scripts to create a text file with some content, create a ZIP file, and insert the text file into the ZIP.

newscript
' write the current input panel to a default text file
WriteScriptToFile ()  ' built-in function 
' create a ZIP file in the default folder
dim myZip= tmpDir & "\myScript.zip"
CreateEmptyZipFolder ( myZip) ' built-in function
' use File System Object to copy the text file into the ZIP
dim objShell = CreateObject("shell.Application")
dim objFolder = objShell.NameSpace( myZip)
objFolder.CopyHere(tmpTxtFile)

If you want to send the ZIP file to the default unZipper, then run

system = myZip


It is possible to take a low level approach to handling files. For example using DLL techniques and APIs such as : fopen, _wcFopen, fread, fwrite, fclose.. An example can be found here NS DLL fopen fwrite fclose.